Sat, 6 May 2000 13:31:34 +0200 Paolo Molaro <lupus@linuxcare.com>
authorPaolo Molaro <lupus@src.gnome.org>
Sat, 6 May 2000 11:57:31 +0000 (11:57 +0000)
committerPaolo Molaro <lupus@src.gnome.org>
Sat, 6 May 2000 11:57:31 +0000 (11:57 +0000)
Sat,  6 May 2000 13:31:34 +0200 Paolo Molaro <lupus@linuxcare.com>

* gdk/nanox/*: nano-X port work in progress.
* gdk/simple.c: simple test for Gdk.
* README.nanox: notes about the port: read this first!
* gtk/gtk{dnd,plug,selection,window}.c: minimal changes to make gtk compile
with nano-X.

35 files changed:
ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
README.nanox [new file with mode: 0644]
gdk/nanox/Makefile.am [new file with mode: 0644]
gdk/nanox/gdkcc-nanox.c [new file with mode: 0644]
gdk/nanox/gdkcolor-nanox.c [new file with mode: 0644]
gdk/nanox/gdkcursor-nanox.c [new file with mode: 0644]
gdk/nanox/gdkdnd-nanox.c [new file with mode: 0644]
gdk/nanox/gdkdrawable-nanox.c [new file with mode: 0644]
gdk/nanox/gdkevents-nanox.c [new file with mode: 0644]
gdk/nanox/gdkfont-nanox.c [new file with mode: 0644]
gdk/nanox/gdkgc-nanox.c [new file with mode: 0644]
gdk/nanox/gdkglobals-nanox.c [new file with mode: 0644]
gdk/nanox/gdkim-nanox.c [new file with mode: 0644]
gdk/nanox/gdkimage-nanox.c [new file with mode: 0644]
gdk/nanox/gdkinput-none.c [new file with mode: 0644]
gdk/nanox/gdkinput.c [new file with mode: 0644]
gdk/nanox/gdkmain-nanox.c [new file with mode: 0644]
gdk/nanox/gdkpixmap-nanox.c [new file with mode: 0644]
gdk/nanox/gdkpolyreg-generic.c [new file with mode: 0644]
gdk/nanox/gdkproperty-nanox.c [new file with mode: 0644]
gdk/nanox/gdkregion-generic.c [new file with mode: 0644]
gdk/nanox/gdkregion-nanox.c [new file with mode: 0644]
gdk/nanox/gdkselection-nanox.c [new file with mode: 0644]
gdk/nanox/gdkvisual-nanox.c [new file with mode: 0644]
gdk/nanox/gdkwindow-nanox.c [new file with mode: 0644]
gtk/gtkdnd.c
gtk/gtkplug.c
gtk/gtkselection.c
gtk/gtkwindow.c

index d7f288f319bb0f6461543b7878f076bd1eb6964a..fa32644a9f6769fdd63720b2767f7f7f2a2a3b06 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Sat,  6 May 2000 13:31:34 +0200 Paolo Molaro <lupus@linuxcare.com>
+
+       * gdk/nanox/*: nano-X port work in progress.
+       * gdk/simple.c: simple test for Gdk.
+       * README.nanox: notes about the port: read this first!
+       * gtk/gtk{dnd,plug,selection,window}.c: minimal changes to make gtk compile
+       with nano-X.
+
 Fri May  5 11:18:47 2000  Owen Taylor  <otaylor@redhat.com>
 
        * gdk/gdkwindow.c gdk/x11/gdkwindow-x11.c (gdk_window_clear): Move
index d7f288f319bb0f6461543b7878f076bd1eb6964a..fa32644a9f6769fdd63720b2767f7f7f2a2a3b06 100644 (file)
@@ -1,3 +1,11 @@
+Sat,  6 May 2000 13:31:34 +0200 Paolo Molaro <lupus@linuxcare.com>
+
+       * gdk/nanox/*: nano-X port work in progress.
+       * gdk/simple.c: simple test for Gdk.
+       * README.nanox: notes about the port: read this first!
+       * gtk/gtk{dnd,plug,selection,window}.c: minimal changes to make gtk compile
+       with nano-X.
+
 Fri May  5 11:18:47 2000  Owen Taylor  <otaylor@redhat.com>
 
        * gdk/gdkwindow.c gdk/x11/gdkwindow-x11.c (gdk_window_clear): Move
index d7f288f319bb0f6461543b7878f076bd1eb6964a..fa32644a9f6769fdd63720b2767f7f7f2a2a3b06 100644 (file)
@@ -1,3 +1,11 @@
+Sat,  6 May 2000 13:31:34 +0200 Paolo Molaro <lupus@linuxcare.com>
+
+       * gdk/nanox/*: nano-X port work in progress.
+       * gdk/simple.c: simple test for Gdk.
+       * README.nanox: notes about the port: read this first!
+       * gtk/gtk{dnd,plug,selection,window}.c: minimal changes to make gtk compile
+       with nano-X.
+
 Fri May  5 11:18:47 2000  Owen Taylor  <otaylor@redhat.com>
 
        * gdk/gdkwindow.c gdk/x11/gdkwindow-x11.c (gdk_window_clear): Move
index d7f288f319bb0f6461543b7878f076bd1eb6964a..fa32644a9f6769fdd63720b2767f7f7f2a2a3b06 100644 (file)
@@ -1,3 +1,11 @@
+Sat,  6 May 2000 13:31:34 +0200 Paolo Molaro <lupus@linuxcare.com>
+
+       * gdk/nanox/*: nano-X port work in progress.
+       * gdk/simple.c: simple test for Gdk.
+       * README.nanox: notes about the port: read this first!
+       * gtk/gtk{dnd,plug,selection,window}.c: minimal changes to make gtk compile
+       with nano-X.
+
 Fri May  5 11:18:47 2000  Owen Taylor  <otaylor@redhat.com>
 
        * gdk/gdkwindow.c gdk/x11/gdkwindow-x11.c (gdk_window_clear): Move
index d7f288f319bb0f6461543b7878f076bd1eb6964a..fa32644a9f6769fdd63720b2767f7f7f2a2a3b06 100644 (file)
@@ -1,3 +1,11 @@
+Sat,  6 May 2000 13:31:34 +0200 Paolo Molaro <lupus@linuxcare.com>
+
+       * gdk/nanox/*: nano-X port work in progress.
+       * gdk/simple.c: simple test for Gdk.
+       * README.nanox: notes about the port: read this first!
+       * gtk/gtk{dnd,plug,selection,window}.c: minimal changes to make gtk compile
+       with nano-X.
+
 Fri May  5 11:18:47 2000  Owen Taylor  <otaylor@redhat.com>
 
        * gdk/gdkwindow.c gdk/x11/gdkwindow-x11.c (gdk_window_clear): Move
index d7f288f319bb0f6461543b7878f076bd1eb6964a..fa32644a9f6769fdd63720b2767f7f7f2a2a3b06 100644 (file)
@@ -1,3 +1,11 @@
+Sat,  6 May 2000 13:31:34 +0200 Paolo Molaro <lupus@linuxcare.com>
+
+       * gdk/nanox/*: nano-X port work in progress.
+       * gdk/simple.c: simple test for Gdk.
+       * README.nanox: notes about the port: read this first!
+       * gtk/gtk{dnd,plug,selection,window}.c: minimal changes to make gtk compile
+       with nano-X.
+
 Fri May  5 11:18:47 2000  Owen Taylor  <otaylor@redhat.com>
 
        * gdk/gdkwindow.c gdk/x11/gdkwindow-x11.c (gdk_window_clear): Move
index d7f288f319bb0f6461543b7878f076bd1eb6964a..fa32644a9f6769fdd63720b2767f7f7f2a2a3b06 100644 (file)
@@ -1,3 +1,11 @@
+Sat,  6 May 2000 13:31:34 +0200 Paolo Molaro <lupus@linuxcare.com>
+
+       * gdk/nanox/*: nano-X port work in progress.
+       * gdk/simple.c: simple test for Gdk.
+       * README.nanox: notes about the port: read this first!
+       * gtk/gtk{dnd,plug,selection,window}.c: minimal changes to make gtk compile
+       with nano-X.
+
 Fri May  5 11:18:47 2000  Owen Taylor  <otaylor@redhat.com>
 
        * gdk/gdkwindow.c gdk/x11/gdkwindow-x11.c (gdk_window_clear): Move
diff --git a/README.nanox b/README.nanox
new file mode 100644 (file)
index 0000000..8c75896
--- /dev/null
@@ -0,0 +1,154 @@
+Gtk port to nano-X
+
+STATUS
+
+Once upon a time I got a few apps working, then started merging
+the new features added by Owen (32 bit sizes for windows and buffering).
+Since then I haven't found the time to work on it:-/
+
+
+TODO
+
+Finish internal window manager abstraction or add proper support in nano-X.
+Fix event polling.
+Implement GdkImage, GdkRgb stuff.
+Put generic region code in generic gdk and/or use the region code from nano-X.
+Fix ugly automake stuff for make dist.
+
+TODO in nano-X
+
+We need to be able to clip and change the background of windows at runtime
+for apps to not look so ugly!
+Fonts: wait for better nano-X font implementation.
+Properties on windows.
+
+
+If you want to work on this port or get additional informnation, get in 
+touch with me.
+To get the beast to compile you also need to apply the patch below
+(any auto* wizard here?): the issue of having two gtk libraries in the
+system needs to be addressed too, maybe use libgtk-x11-1.4.so and 
+libgtk-nanox-1.4.so ...
+
+Paolo Molaro
+lupus@linuxcare.com
+
+
+Index: acconfig.h
+===================================================================
+RCS file: /cvs/gnome/gtk+/acconfig.h,v
+retrieving revision 1.16
+diff -u -r1.16 acconfig.h
+--- acconfig.h 1999/03/20 00:52:29     1.16
++++ acconfig.h 2000/05/06 11:52:38
+@@ -49,6 +49,8 @@
+ /* Most machines will be happy with int or void.  IRIX requires '...' */
+ #undef SIGNAL_ARG_TYPE
++#undef USE_NANOX
++
+ /* #undef PACKAGE */
+ /* #undef VERSION */
+Index: configure.in
+===================================================================
+RCS file: /cvs/gnome/gtk+/configure.in,v
+retrieving revision 1.142
+diff -u -r1.142 configure.in
+--- configure.in       2000/05/04 00:29:46     1.142
++++ configure.in       2000/05/06 11:52:38
+@@ -99,6 +99,8 @@
+ AC_ARG_WITH(locale, [  --with-locale=LOCALE    locale name you want to use ])
+ AC_ARG_WITH(xinput, [  --with-xinput=[no/gxi/xfree] support XInput ])
++AC_ARG_ENABLE(nanox, [  --enable-nanox            use nano-X instead of X11 [default=no]],
++                      , enable_nanox="no")
+ if test "x$enable_debug" = "xyes"; then
+   test "$cflags_set" = set || CFLAGS="$CFLAGS -g"
+@@ -322,6 +324,8 @@
+ saved_cflags="$CFLAGS"
+ saved_ldflags="$LDFLAGS"
++if text "x$enable_nanox" = "xno"; then
++
+ CFLAGS="$CFLAGS $X_CFLAGS"
+ LDFLAGS="$LDFLAGS $X_LDFLAGS $X_LIBS"
+@@ -465,6 +469,13 @@
+   GTK_LOCALE_FLAGS="-DX_LOCALE"
+ fi
++else
++AC_CHECK_LIB(nano-X, GrOpen)
++LIBS="-lnano-X $LIBS"
++ AC_DEFINE(USE_NANOX)
++AM_CONDITIONAL(USE_NANOX, test x$enable_nanox = xyes)
++fi # if enable_nanox
++
+ # Checks for header files.
+ AC_HEADER_STDC
+@@ -602,8 +613,13 @@
+ esac
+ ],[
+ # Currently we always use X11 on those systems where we run configure...
++if test x$enable_nanox = xno; then
+ gdk_windowing='
+ #define GDK_WINDOWING_X11'
++else
++gdk_windowing='
++#define GDK_WINDOWING_NANOX'
++fi
+ if test x$gdk_wchar_h = xyes; then
+   gdk_wc='
+ #define GDK_HAVE_WCHAR_H 1'
+@@ -629,6 +645,7 @@
+ docs/Makefile
+ gdk/Makefile
+ gdk/x11/Makefile
++gdk/nanox/Makefile
+ gdk/win32/Makefile
+ gtk/Makefile
+ gtk/gtkfeatures.h
+Index: gdk/Makefile.am
+===================================================================
+RCS file: /cvs/gnome/gtk+/gdk/Makefile.am,v
+retrieving revision 1.41
+diff -u -r1.41 Makefile.am
+--- gdk/Makefile.am    2000/04/05 04:11:10     1.41
++++ gdk/Makefile.am    2000/05/06 11:52:38
+@@ -1,6 +1,10 @@
+ ## Makefile.am for gtk+/gdk
++if USE_NANOX
++SUBDIRS=win32 nanox
++else
+ SUBDIRS=x11 win32
++endif
+ EXTRA_DIST =  \
+       gdkconfig.h.win32 \
+@@ -36,8 +40,13 @@
+       -lm             \
+ @STRIP_END@
++if USE_NANOX
+ libgdk_la_LIBADD = \
++      nanox/libgdk-nanox.la   
++else
++libgdk_la_LIBADD = \
+       x11/libgdk-x11.la       
++endif
+ #
+ # setup source file variables
+@@ -138,3 +147,8 @@
+       @files=`ls $(DISTFILES) 2> /dev/null `; for p in $$files; do \
+         echo $$p; \
+       done
++
++noinst_PROGRAMS = simple
++simple_DEPENDENCIES = libgdk.la simple.c
++simple_LDADD = libgdk.la
++
diff --git a/gdk/nanox/Makefile.am b/gdk/nanox/Makefile.am
new file mode 100644 (file)
index 0000000..fc3d1a5
--- /dev/null
@@ -0,0 +1,51 @@
+## Process this file with automake to produce Makefile.in
+
+INCLUDES = @STRIP_BEGIN@       \
+       -DG_LOG_DOMAIN=\"Gdk\"  \
+       -I$(top_srcdir)         \
+       -I$(top_srcdir)/gdk     \
+       @GTK_DEBUG_FLAGS@       \
+       @GTK_XIM_FLAGS@         \
+       @GTK_LOCALE_FLAGS@      \
+       @GLIB_CFLAGS@           \
+       @x_cflags@              \
+@STRIP_END@
+
+LDADDS = @STRIP_BEGIN@         \
+       @x_ldflags@     \
+       @x_libs@        \
+       @GLIB_LIBS@     \
+       -lm             \
+@STRIP_END@
+
+noinst_LTLIBRARIES = libgdk-nanox.la
+
+xinput_sources =          \
+       gdkinput-none.c
+
+libgdk_nanox_la_SOURCES =    \
+       gdkcc-nanox.c      \
+       gdkcolor-nanox.c           \
+       gdkcursor-nanox.c          \
+       gdkdnd-nanox.c     \
+       gdkdrawable-nanox.c  \
+       gdkevents-nanox.c          \
+       gdkfont-nanox.c    \
+       gdkgc-nanox.c      \
+       gdkglobals-nanox.c   \
+       gdkim-nanox.c      \
+       gdkimage-nanox.c           \
+       gdkinput.c         \
+       gdkmain-nanox.c    \
+       gdkpixmap-nanox.c          \
+       gdkpolyreg-generic.c    \
+       gdkproperty-nanox.c  \
+       gdkregion-generic.c        \
+       gdkselection-nanox.c \
+       gdkvisual-nanox.c          \
+       gdkwindow-nanox.c    \
+       gdknanox.h                 \
+       gdkprivate-nanox.h   \
+       gdkinput-none.c
+
+
diff --git a/gdk/nanox/gdkcc-nanox.c b/gdk/nanox/gdkcc-nanox.c
new file mode 100644 (file)
index 0000000..3589924
--- /dev/null
@@ -0,0 +1,119 @@
+#include "gdk.h"
+#include "gdkprivate-nanox.h"
+
+GdkColorContext *
+gdk_color_context_new (GdkVisual   *visual,
+                      GdkColormap *colormap)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+  return NULL;
+}
+
+GdkColorContext *
+gdk_color_context_new_mono (GdkVisual   *visual,
+                           GdkColormap *colormap)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+  return NULL;
+}
+
+void
+gdk_color_context_free (GdkColorContext *cc)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+}
+
+
+gulong
+gdk_color_context_get_pixel (GdkColorContext *cc,
+                            gushort          red,
+                            gushort          green,
+                            gushort          blue,
+                            gint            *failed)
+{
+  return RGB2PIXEL(red, green, blue);
+}
+
+void
+gdk_color_context_get_pixels (GdkColorContext *cc,
+                             gushort         *reds,
+                             gushort         *greens,
+                             gushort         *blues,
+                             gint             ncolors,
+                             gulong          *colors,
+                             gint            *nallocated)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+}
+
+void
+gdk_color_context_get_pixels_incremental (GdkColorContext *cc,
+                                         gushort         *reds,
+                                         gushort         *greens,
+                                         gushort         *blues,
+                                         gint             ncolors,
+                                         gint            *used,
+                                         gulong          *colors,
+                                         gint            *nallocated)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+}
+
+gint
+gdk_color_context_query_color (GdkColorContext *cc,
+                              GdkColor        *color)
+{
+  return gdk_color_context_query_colors (cc, color, 1);
+}
+
+gint
+gdk_color_context_query_colors (GdkColorContext *cc,
+                               GdkColor        *colors,
+                               gint             num_colors)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+  return 0;
+}
+
+gint
+gdk_color_context_add_palette (GdkColorContext *cc,
+                              GdkColor        *palette,
+                              gint             num_palette)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+  return 0;
+}
+
+void
+gdk_color_context_init_dither (GdkColorContext *cc)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+}
+
+void
+gdk_color_context_free_dither (GdkColorContext *cc)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+}
+
+gulong
+gdk_color_context_get_pixel_from_palette (GdkColorContext *cc,
+                                         gushort         *red,
+                                         gushort         *green,
+                                         gushort         *blue,
+                                         gint            *failed)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+  return 0;
+}
+
+guchar
+gdk_color_context_get_index_from_palette (GdkColorContext *cc,
+                                         gint            *red,
+                                         gint            *green,
+                                         gint            *blue,
+                                         gint            *failed)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+  return 0;
+}
diff --git a/gdk/nanox/gdkcolor-nanox.c b/gdk/nanox/gdkcolor-nanox.c
new file mode 100644 (file)
index 0000000..e0fb65b
--- /dev/null
@@ -0,0 +1,238 @@
+#include "gdk.h"
+#include "gdkprivate-nanox.h"
+#include <stdlib.h>
+#include <string.h>
+
+GdkColormap*
+gdk_colormap_new (GdkVisual *visual,
+                 gboolean   private_cmap)
+{
+  GdkColormap *colormap;
+  GdkColormapPrivateX *private;
+  int size;
+  int i;
+
+  g_return_val_if_fail (visual != NULL, NULL);
+
+  private = g_new (GdkColormapPrivateX, 1);
+  colormap = (GdkColormap*) private;
+
+  private->base.visual = visual;
+  private->base.ref_count = 1;
+
+  colormap->size = visual->colormap_size;
+  colormap->colors = NULL;
+
+  return colormap;
+}
+
+void
+_gdk_colormap_real_destroy (GdkColormap *colormap)
+{
+}
+
+
+void
+gdk_colormap_sync (GdkColormap *colormap,
+                  gboolean     force)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+}
+
+GdkColormap*
+gdk_colormap_get_system (void)
+{
+  return gdk_colormap_new(gdk_visual_get_system(), 0);
+}
+
+
+gint
+gdk_colormap_get_system_size (void)
+{
+    GR_PALETTE palette;
+
+    GrGetSystemPalette(&palette);
+    return palette.count;
+}
+
+void
+gdk_colormap_change (GdkColormap *colormap,
+                    gint         ncolors)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+}
+
+gboolean
+gdk_colors_alloc (GdkColormap   *colormap,
+                 gboolean       contiguous,
+                 gulong        *planes,
+                 gint           nplanes,
+                 gulong        *pixels,
+                 gint           npixels)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+  return 1;
+}
+
+static struct cspec {
+               char *name;
+               int red, green, blue;
+} cnames [] = {
+               {"white", 0xffff, 0xffff, 0xffff},
+               {"black", 0, 0, 0},
+               {"red", 0xffff, 0, 0},
+               {"green", 0, 0xffff, 0},
+               {"blue", 0, 0, 0xffff},
+               {NULL}
+};
+
+gboolean
+gdk_color_parse (const gchar *spec,
+                GdkColor *color)
+{
+  int size, csize, i, j, shift;
+  double dval;
+  gchar *end;
+  int scale[] = {0, 4096, 256, 16, 1};
+  int add[] = {0, 4095, 255, 15, 1};
+  
+  g_return_val_if_fail(spec != NULL, 0);
+  g_return_val_if_fail(color != NULL, 0);
+
+  g_message("color parsing %s", spec);
+
+  if (*spec == '#') {
+       spec++;
+       size = strlen(spec);
+       csize = size/3;
+       shift = 16-csize*4;
+       if (size > 12 || size % 3)
+         return 0;
+       j = spec[csize];
+       spec[csize] = 0;
+       color->red = strtol(spec, &end, 16) << shift;
+       if (end == spec || *end != '\0')
+         return 0;
+       spec[csize] = j;
+       spec += csize;
+       /* green */
+       j = spec[csize];
+       spec[csize] = 0;
+       color->green = strtol(spec, &end, 16) << shift;
+       if (end == spec || *end != '\0')
+         return 0;
+       spec[csize] = j;
+       spec += csize;
+       /* blue */
+       color->blue = strtol(spec, &end, 16) << shift;
+       if (end == spec || *end != '\0')
+         return 0;
+       return 1;
+  } else if (!strncmp(spec, "rgb:", 4)) {
+       spec += 4;
+       color->red = strtol(spec, &end, 16);
+       if (end == spec || *end != '/')
+         return 0;
+       csize = end-spec;
+       color->red *= scale[csize];
+       color->red += add[csize];
+       spec += csize + 1;
+       /* green */
+       color->green = strtol(spec, &end, 16);
+       if (end == spec || *end != '/')
+         return 0;
+       csize = end-spec;
+       color->green *= scale[csize];
+       color->green += add[csize];
+       spec += csize + 1;
+       /* blue */
+       color->blue = strtol(spec, &end, 16);
+       if (end == spec || *end != '\0')
+         return 0;
+       csize = end-spec;
+       color->blue *= scale[csize];
+       color->blue += add[csize];
+       return 1;
+  } else if (!strncmp(spec, "rgbi:", 5)) {
+       spec += 5;
+       dval = strtod(spec, &end);
+       if (end == spec || *end != '/' || dval > 1.0 || dval < 0)
+         return 0;
+       color->red = dval*0xffff;
+       spec += end-spec + 1;
+       /* green */
+       dval = strtod(spec, &end);
+       if (end == spec || *end != '/' || dval > 1.0 || dval < 0)
+         return 0;
+       color->green = dval*0xffff;
+       spec += end-spec + 1;
+       /* blue */
+       dval = strtod(spec, &end);
+       if (end == spec || *end != '0' || dval > 1.0 || dval < 0)
+         return 0;
+       color->blue = dval*0xffff;
+       return 1;
+  } else {
+    /* use a cdb database, instead, later */
+       for (i=0; cnames[i].name; ++i) {
+                       if (strcmp(cnames[i].name, spec))
+                                       continue;
+                       color->red = cnames[i].red;
+                       color->green = cnames[i].green;
+                       color->blue = cnames[i].blue;
+                       return 1;
+       }
+       if (spec[0] == 'g' && spec[1] == 'r' && (spec[2] == 'a' || spec[2] == 'e') && spec[3] == 'y') {
+               dval = strtol(spec+4, NULL, 10)/100;
+               color->red = color->green = color->blue = 255 * dval;
+               return 1;
+       }
+  }
+  
+  return 0;
+}
+
+void
+gdk_colors_free (GdkColormap *colormap,
+                gulong      *in_pixels,
+                gint         in_npixels,
+                gulong       planes)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+}
+
+void
+gdk_colormap_free_colors (GdkColormap *colormap,
+                         GdkColor    *colors,
+                         gint         ncolors)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+}
+
+
+gint
+gdk_colormap_alloc_colors (GdkColormap *colormap,
+                          GdkColor    *colors,
+                          gint         ncolors,
+                          gboolean     writeable,
+                          gboolean     best_match,
+                          gboolean    *success)
+{
+  int i;
+
+  for (i=0; i < ncolors;++i)
+    colors[i].pixel = RGB2PIXEL(colors[i].red>>8, colors[i].green>>8, colors[i].blue>>8);
+  success = 1;
+  return 1;
+}
+
+
+gboolean
+gdk_color_change (GdkColormap *colormap,
+                 GdkColor    *color)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+  return 1;
+}
+
+
diff --git a/gdk/nanox/gdkcursor-nanox.c b/gdk/nanox/gdkcursor-nanox.c
new file mode 100644 (file)
index 0000000..a3b7fb0
--- /dev/null
@@ -0,0 +1,26 @@
+#include "gdk.h"
+#include "gdkprivate-nanox.h"
+
+GdkCursor*
+gdk_cursor_new (GdkCursorType cursor_type) {
+               g_message("unimplemented %s", __FUNCTION__);
+       return NULL;
+}
+
+GdkCursor*
+gdk_cursor_new_from_pixmap (GdkPixmap *source,
+                           GdkPixmap *mask,
+                           GdkColor  *fg,
+                           GdkColor  *bg,
+                           gint       x,
+                           gint       y)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+               return NULL;
+}
+
+void
+_gdk_cursor_destroy (GdkCursor *cursor)
+{
+}
+
diff --git a/gdk/nanox/gdkdnd-nanox.c b/gdk/nanox/gdkdnd-nanox.c
new file mode 100644 (file)
index 0000000..d9fc055
--- /dev/null
@@ -0,0 +1,121 @@
+#include "gdk.h"
+#include "gdkprivate-nanox.h"
+
+
+GdkDragContext *
+gdk_drag_context_new        (void)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+  return NULL;
+}
+
+void            
+gdk_drag_context_ref (GdkDragContext *context)
+{
+}
+
+void            
+gdk_drag_context_unref (GdkDragContext *context)
+{
+}
+
+void
+gdk_dnd_init (void)
+{
+}
+
+GdkDragContext * 
+gdk_drag_begin (GdkWindow     *window,
+               GList         *targets)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+  return NULL;
+}
+
+guint32
+gdk_drag_get_protocol (guint32          xid,
+                      GdkDragProtocol *protocol)
+{
+  *protocol = GDK_DRAG_PROTO_NONE;
+  return 0;
+}
+
+void
+gdk_drag_find_window (GdkDragContext  *context,
+                     GdkWindow       *drag_window,
+                     gint             x_root,
+                     gint             y_root,
+                     GdkWindow      **dest_window,
+                     GdkDragProtocol *protocol)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+}
+
+
+gboolean        
+gdk_drag_motion (GdkDragContext *context,
+                GdkWindow      *dest_window,
+                GdkDragProtocol protocol,
+                gint            x_root, 
+                gint            y_root,
+                GdkDragAction   suggested_action,
+                GdkDragAction   possible_actions,
+                guint32         time)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+}
+
+
+void
+gdk_drag_drop (GdkDragContext *context,
+              guint32         time)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+}
+
+
+void
+gdk_drag_abort (GdkDragContext *context,
+               guint32         time)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+}
+
+void             
+gdk_drag_status (GdkDragContext   *context,
+                GdkDragAction     action,
+                guint32           time)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+}
+
+void 
+gdk_drop_reply (GdkDragContext   *context,
+               gboolean          ok,
+               guint32           time)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+}
+
+void             
+gdk_drop_finish (GdkDragContext   *context,
+                gboolean          success,
+                guint32           time)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+}
+
+
+void            
+gdk_window_register_dnd (GdkWindow      *window)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+}
+
+GdkAtom       
+gdk_drag_get_selection (GdkDragContext *context)
+{
+  return GDK_NONE;
+}
+
+
diff --git a/gdk/nanox/gdkdrawable-nanox.c b/gdk/nanox/gdkdrawable-nanox.c
new file mode 100644 (file)
index 0000000..10c6704
--- /dev/null
@@ -0,0 +1,271 @@
+#include "gdk.h"
+#include "gdkprivate-nanox.h"
+
+static void    gdk_nanox_drawable_destroy   (GdkDrawable     *drawable);
+
+static void gdk_nanox_draw_rectangle (GdkDrawable    *drawable,
+                                   GdkGC          *gc,
+                                   gint            filled,
+                                   gint            x,
+                                   gint            y,
+                                   gint            width,
+                                   gint            height);
+static void gdk_nanox_draw_arc       (GdkDrawable    *drawable,
+                                   GdkGC          *gc,
+                                   gint            filled,
+                                   gint            x,
+                                   gint            y,
+                                   gint            width,
+                                   gint            height,
+                                   gint            angle1,
+                                   gint            angle2);
+static void gdk_nanox_draw_polygon   (GdkDrawable    *drawable,
+                                   GdkGC          *gc,
+                                   gint            filled,
+                                   GdkPoint       *points,
+                                   gint            npoints);
+static void gdk_nanox_draw_text      (GdkDrawable    *drawable,
+                                   GdkFont        *font,
+                                   GdkGC          *gc,
+                                   gint            x,
+                                   gint            y,
+                                   const gchar    *text,
+                                   gint            text_length);
+static void gdk_nanox_draw_text_wc   (GdkDrawable    *drawable,
+                                   GdkFont        *font,
+                                   GdkGC          *gc,
+                                   gint            x,
+                                   gint            y,
+                                   const GdkWChar *text,
+                                   gint            text_length);
+static void gdk_nanox_draw_drawable  (GdkDrawable    *drawable,
+                                   GdkGC          *gc,
+                                   GdkPixmap      *src,
+                                   gint            xsrc,
+                                   gint            ysrc,
+                                   gint            xdest,
+                                   gint            ydest,
+                                   gint            width,
+                                   gint            height);
+static void gdk_nanox_draw_points    (GdkDrawable    *drawable,
+                                   GdkGC          *gc,
+                                   GdkPoint       *points,
+                                   gint            npoints);
+static void gdk_nanox_draw_segments  (GdkDrawable    *drawable,
+                                   GdkGC          *gc,
+                                   GdkSegment     *segs,
+                                   gint            nsegs);
+static void gdk_nanox_draw_lines     (GdkDrawable    *drawable,
+                                   GdkGC          *gc,
+                                   GdkPoint       *points,
+                                   gint            npoints);
+
+GdkDrawableClass _gdk_nanox_drawable_class = {
+  gdk_nanox_drawable_destroy,
+  _gdk_nanox_gc_new,
+  gdk_nanox_draw_rectangle,
+  gdk_nanox_draw_arc,
+  gdk_nanox_draw_polygon,
+  gdk_nanox_draw_text,
+  gdk_nanox_draw_text_wc,
+  gdk_nanox_draw_drawable,
+  gdk_nanox_draw_points,
+  gdk_nanox_draw_segments,
+  gdk_nanox_draw_lines
+};
+
+GdkColormap*
+gdk_drawable_get_colormap (GdkDrawable *drawable)
+{
+  GdkDrawablePrivate *drawable_private;
+  
+  g_return_val_if_fail (drawable != NULL, NULL);
+  drawable_private = (GdkDrawablePrivate*) drawable;
+  
+  if (!GDK_DRAWABLE_DESTROYED (drawable))
+    {
+      if (drawable_private->colormap == NULL &&
+         GDK_IS_WINDOW (drawable))
+       {
+         /*XGetWindowAttributes (GDK_DRAWABLE_XDISPLAY (drawable),
+                               GDK_DRAWABLE_XID (drawable),
+                               &window_attributes);
+         drawable_private->colormap =  gdk_colormap_lookup (window_attributes.colormap);*/
+       }
+
+      return drawable_private->colormap;
+    }
+  
+  return NULL;
+}
+
+void
+gdk_drawable_set_colormap (GdkDrawable *drawable,
+                          GdkColormap *colormap)
+{
+  GdkDrawablePrivate *drawable_private;
+  GdkColormapPrivateX *colormap_private;
+  
+  g_return_if_fail (drawable != NULL);
+  g_return_if_fail (colormap != NULL);
+  
+  drawable_private = (GdkDrawablePrivate *)drawable;
+  colormap_private = (GdkColormapPrivateX *)colormap;
+  
+  if (!GDK_DRAWABLE_DESTROYED (drawable))
+    {
+      if (GDK_IS_WINDOW (drawable))
+       {
+         g_return_if_fail (colormap_private->base.visual !=
+                           ((GdkColormapPrivate *)(drawable_private->colormap))->visual);
+
+       }
+
+      if (drawable_private->colormap)
+       gdk_colormap_unref (drawable_private->colormap);
+      drawable_private->colormap = colormap;
+      gdk_colormap_ref (drawable_private->colormap);
+
+      if (GDK_IS_WINDOW (drawable) &&
+         drawable_private->window_type != GDK_WINDOW_TOPLEVEL)
+       /*gdk_window_add_colormap_windows (drawable);*/;
+    }
+}
+
+static void 
+gdk_nanox_drawable_destroy (GdkDrawable *drawable)
+{
+  
+}
+
+static void
+gdk_nanox_draw_rectangle (GdkDrawable *drawable,
+                       GdkGC       *gc,
+                       gint         filled,
+                       gint         x,
+                       gint         y,
+                       gint         width,
+                       gint         height)
+{
+  if (filled)
+    GrFillRect (GDK_DRAWABLE_XID (drawable), GDK_GC_XGC (gc), x, y, width, height);
+  else
+    GrRect (GDK_DRAWABLE_XID (drawable), GDK_GC_XGC (gc), x, y, width, height);
+}
+
+static void
+gdk_nanox_draw_arc (GdkDrawable *drawable,
+                 GdkGC       *gc,
+                 gint         filled,
+                 gint         x,
+                 gint         y,
+                 gint         width,
+                 gint         height,
+                 gint         angle1,
+                 gint         angle2)
+{
+               /* this is not an arc, obviously */
+  if (filled)
+    GrFillEllipse (GDK_DRAWABLE_XID (drawable), GDK_GC_XGC (gc), x, y, width/2, height/2);
+  else
+    GrEllipse (GDK_DRAWABLE_XID (drawable), GDK_GC_XGC (gc), x, y, width/2, height/2);
+}
+
+static void
+gdk_nanox_draw_polygon (GdkDrawable *drawable,
+                     GdkGC       *gc,
+                     gint         filled,
+                     GdkPoint    *points,
+                     gint         npoints)
+{
+  GR_POINT *new_points = g_new(GR_POINT, npoints);
+  int i;
+  for (i=0; i < npoints;++i) {
+    new_points[i].x = points[i].x;
+    new_points[i].y = points[i].y;
+  }
+  if (filled)
+    {
+      GrFillPoly (GDK_DRAWABLE_XID (drawable), GDK_GC_XGC (gc), npoints, new_points);
+    }
+  else
+    {
+      GrPoly (GDK_DRAWABLE_XID (drawable), GDK_GC_XGC (gc), npoints, new_points);
+    }
+  g_free(new_points);
+}
+
+static void
+gdk_nanox_draw_text (GdkDrawable *drawable,
+                  GdkFont     *font,
+                  GdkGC       *gc,
+                  gint         x,
+                  gint         y,
+                  const gchar *text,
+                  gint         text_length)
+{
+  GrSetGCFont(GDK_GC_XGC(gc), GDK_FONT_XFONT(font));
+  GrText (GDK_DRAWABLE_XID (drawable), GDK_GC_XGC (gc), x, y, text, text_length, TF_UTF8|TF_BASELINE);
+}
+
+static void
+gdk_nanox_draw_text_wc (GdkDrawable    *drawable,
+                     GdkFont        *font,
+                     GdkGC          *gc,
+                     gint            x,
+                     gint            y,
+                     const GdkWChar *text,
+                     gint            text_length)
+{
+  GrSetGCFont(GDK_GC_XGC(gc), GDK_FONT_XFONT(font));
+  GrText (GDK_DRAWABLE_XID (drawable), GDK_GC_XGC (gc), x, y, text, text_length, TF_UC32|TF_BASELINE);
+}
+
+static void
+gdk_nanox_draw_drawable (GdkDrawable *drawable,
+                      GdkGC       *gc,
+                      GdkPixmap   *src,
+                      gint         xsrc,
+                      gint         ysrc,
+                      gint         xdest,
+                      gint         ydest,
+                      gint         width,
+                      gint         height)
+{
+  GrCopyArea(GDK_DRAWABLE_XID(drawable), GDK_GC_XGC(gc), xdest, ydest,
+       width, height, GDK_DRAWABLE_XID(src), xsrc, ysrc, 0);
+}
+
+static void
+gdk_nanox_draw_points (GdkDrawable *drawable,
+                    GdkGC       *gc,
+                    GdkPoint    *points,
+                    gint         npoints)
+{
+  int i;
+  for (i=0; i < npoints; ++i)
+    GrPoint(GDK_DRAWABLE_XID(drawable), GDK_GC_XGC(gc), points[i].x, points[i].y);
+}
+
+static void
+gdk_nanox_draw_segments (GdkDrawable *drawable,
+                      GdkGC       *gc,
+                      GdkSegment  *segs,
+                      gint         nsegs)
+{
+  int i;
+  for (i=0; i < nsegs; ++i)
+       GrLine(GDK_DRAWABLE_XID(drawable), GDK_GC_XGC(gc), segs[i].x1, segs[i].y1, segs[i].x2, segs[i].y2);
+}
+
+static void
+gdk_nanox_draw_lines (GdkDrawable *drawable,
+                   GdkGC       *gc,
+                   GdkPoint    *points,
+                   gint         npoints)
+{
+  int i;
+  for (i=0; i < npoints-1; ++i)
+       GrLine(GDK_DRAWABLE_XID(drawable), GDK_GC_XGC(gc), points[i].x, points[i].y, points[i+1].x, points[i+1].y);
+}
+
diff --git a/gdk/nanox/gdkevents-nanox.c b/gdk/nanox/gdkevents-nanox.c
new file mode 100644 (file)
index 0000000..81d9cb4
--- /dev/null
@@ -0,0 +1,441 @@
+#include "gdk.h"
+#include "gdkinternals.h"
+#include "gdkprivate-nanox.h"
+
+typedef struct _GdkEventPrivate GdkEventPrivate;
+
+#define DOUBLE_CLICK_TIME      250
+#define TRIPLE_CLICK_TIME      500
+#define DOUBLE_CLICK_DIST      5
+#define TRIPLE_CLICK_DIST      5
+
+#define GR_BUTTON_TO_GDK(b) b&LBUTTON? 1: (b&MBUTTON? 2: (b&RBUTTON? 3: 0))
+
+static guint gr_mod_to_gdk(guint mods, guint buttons) {
+       guint res=0;
+       if (mods & GR_MODIFIER_SHIFT)
+                       res |= GDK_SHIFT_MASK;
+       if (mods & GR_MODIFIER_CTRL)
+                       res |= GDK_CONTROL_MASK;
+       if (mods & GR_MODIFIER_META)
+                       res |= GDK_MOD1_MASK;
+       if (buttons & LBUTTON)
+                       res |= GDK_BUTTON1_MASK;
+       if (buttons & MBUTTON)
+                       res |= GDK_BUTTON2_MASK;
+       if (buttons & RBUTTON)
+                       res |= GDK_BUTTON3_MASK;
+       return res;
+}
+
+static gboolean  gdk_event_prepare      (gpointer   source_data, 
+                                        GTimeVal  *current_time,
+                                        gint      *timeout,
+                                        gpointer   user_data);
+static gboolean  gdk_event_check        (gpointer   source_data,
+                                        GTimeVal  *current_time,
+                                        gpointer   user_data);
+static gboolean  gdk_event_dispatch     (gpointer   source_data,
+                                        GTimeVal  *current_time,
+                                        gpointer   user_data);
+
+typedef enum
+{
+  /* Following flag is set for events on the event queue during
+   * translation and cleared afterwards.
+   */
+  GDK_EVENT_PENDING = 1 << 0
+} GdkEventFlags;
+
+struct _GdkEventPrivate
+{
+  GdkEvent event;
+  guint    flags;
+};
+
+
+static GSourceFuncs event_funcs = {
+  gdk_event_prepare,
+  gdk_event_check,
+  gdk_event_dispatch,
+  (GDestroyNotify)g_free
+};
+
+GPollFD event_poll_fd;
+extern int sock;
+static guint serial_value = 1;
+
+static int
+events_idle () {
+    gdk_events_queue();
+    return TRUE;
+}
+
+void 
+gdk_events_init (void)
+{
+  g_source_add (GDK_PRIORITY_EVENTS, TRUE, &event_funcs, NULL, NULL, NULL);
+
+  event_poll_fd.fd = sock;
+  event_poll_fd.events = G_IO_IN;
+  
+  g_main_add_poll (&event_poll_fd, GDK_PRIORITY_EVENTS);
+
+  g_idle_add(events_idle, NULL);
+
+}
+
+static gboolean  
+gdk_event_prepare (gpointer  source_data, 
+                  GTimeVal *current_time,
+                  gint     *timeout,
+                  gpointer  user_data)
+{
+  gboolean retval;
+  
+  GDK_THREADS_ENTER ();
+
+  *timeout = -1;
+
+  retval = (gdk_event_queue_find_first () != NULL);
+
+  GDK_THREADS_LEAVE ();
+
+  return retval;
+}
+
+static gboolean  
+gdk_event_check (gpointer  source_data,
+                GTimeVal *current_time,
+                gpointer  user_data)
+{
+  gboolean retval;
+  
+  GDK_THREADS_ENTER ();
+
+  if (event_poll_fd.revents & G_IO_IN)
+    //retval = (gdk_event_queue_find_first () != NULL);
+    retval = 1;
+  else
+    retval = FALSE;
+
+  GDK_THREADS_LEAVE ();
+
+  return retval;
+}
+
+static gboolean  
+gdk_event_dispatch (gpointer  source_data,
+                   GTimeVal *current_time,
+                   gpointer  user_data)
+{
+  GdkEvent *event;
+  GDK_THREADS_ENTER ();
+
+  gdk_events_queue();
+  event = gdk_event_unqueue();
+
+  if (event)
+    {
+      if (gdk_event_func)
+       (*gdk_event_func) (event, gdk_event_data);
+      
+      gdk_event_free (event);
+    }
+  
+  GDK_THREADS_LEAVE ();
+
+  return TRUE;
+}
+
+
+gboolean
+gdk_events_pending (void)
+{
+  return gdk_event_queue_find_first();
+}
+
+GdkEvent*
+gdk_event_get_graphics_expose (GdkWindow *window)
+{
+  return NULL;
+}
+
+static gint gdk_event_translate (GdkEvent *event, GR_EVENT *xevent) {
+  GdkWindow *window=NULL;
+  GdkWindowPrivate *window_private=NULL;
+  gint return_val = FALSE;
+  static int lastx=0, lasty=0, lastrootx=0, lastrooty=0;
+
+  if (xevent->type == GR_EVENT_TYPE_FDINPUT)
+       return 0;
+  window = gdk_window_lookup (xevent->general.wid);
+  /* FIXME: window might be a GdkPixmap!!! */
+  
+  window_private = (GdkWindowPrivate *) window;
+  
+  if (window != NULL)
+    gdk_window_ref (window);
+  
+  event->any.window = window;
+  event->any.send_event = FALSE;
+  if (window_private && GDK_DRAWABLE_DESTROYED (window))
+    {
+       return FALSE;
+    }
+  else
+    {
+      /* Check for filters for this window
+       */
+      GdkFilterReturn result = GDK_FILTER_CONTINUE;
+      /*result = gdk_event_apply_filters (xevent, event,
+                                       window_private
+                                       ?window_private->filters
+                                       :gdk_default_filters);
+      */
+      if (result != GDK_FILTER_CONTINUE)
+       {
+         return (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE;
+       }
+    }
+
+  return_val = TRUE;
+
+      //g_message("got event (%p) %d", window, xevent->type);
+  switch (xevent->type)
+    {
+    case GR_EVENT_TYPE_KEY_DOWN:
+      event->key.keyval = xevent->keystroke.ch;
+      event->key.type = GDK_KEY_PRESS;
+      event->key.window = window;
+      event->key.time = serial_value++;
+      event->key.state = gr_mod_to_gdk(xevent->keystroke.modifiers, xevent->keystroke.buttons);
+      event->key.string = g_strdup_printf ("%c", xevent->keystroke.ch);
+      event->key.length = 1;
+      
+      break;
+    case GR_EVENT_TYPE_KEY_UP:
+      event->key.keyval = xevent->keystroke.ch;
+      event->key.type = GDK_KEY_RELEASE;
+      event->key.window = window;
+      event->key.time = serial_value++;
+      event->key.state = gr_mod_to_gdk(xevent->keystroke.modifiers, xevent->keystroke.buttons)|GDK_RELEASE_MASK;
+      event->key.string = NULL;
+      event->key.length = 0;
+      
+      break;
+    case GR_EVENT_TYPE_BUTTON_DOWN:
+         event->button.type = GDK_BUTTON_PRESS;
+         event->button.window = window;
+         event->button.time = serial_value++;
+         event->button.x = xevent->button.x;
+         event->button.y = xevent->button.y;
+         event->button.x_root = (gfloat)xevent->button.rootx;
+         event->button.y_root = (gfloat)xevent->button.rooty;
+         event->button.pressure = 0.5;
+         event->button.xtilt = 0;
+         event->button.ytilt = 0;
+      event->button.state = gr_mod_to_gdk(xevent->button.modifiers, xevent->button.buttons);
+         event->button.button = GR_BUTTON_TO_GDK(xevent->button.changebuttons);
+         event->button.source = GDK_SOURCE_MOUSE;
+         event->button.deviceid = GDK_CORE_POINTER;
+         g_message("button down: %d", event->button.button);
+         gdk_event_button_generate (event);
+      break;
+    case GR_EVENT_TYPE_BUTTON_UP:
+         event->button.type = GDK_BUTTON_RELEASE;
+         event->button.window = window;
+         event->button.time = serial_value++;
+         event->button.x = xevent->button.x;
+         event->button.y = xevent->button.y;
+         event->button.x_root = (gfloat)xevent->button.rootx;
+         event->button.y_root = (gfloat)xevent->button.rooty;
+         event->button.pressure = 0.5;
+         event->button.xtilt = 0;
+         event->button.ytilt = 0;
+      event->button.state = gr_mod_to_gdk(xevent->button.modifiers, xevent->button.buttons)|GDK_RELEASE_MASK;
+         event->button.button = GR_BUTTON_TO_GDK(xevent->button.changebuttons);
+         event->button.source = GDK_SOURCE_MOUSE;
+         event->button.deviceid = GDK_CORE_POINTER;
+         g_message("button up: %d", event->button.button);
+         gdk_event_button_generate (event);
+      break;
+    case GR_EVENT_TYPE_MOUSE_MOTION:
+      event->motion.type = GDK_MOTION_NOTIFY;
+      event->motion.window = window;
+      event->motion.time = serial_value++;
+         event->motion.x = xevent->mouse.x;
+         event->motion.y = xevent->mouse.y;
+         event->motion.x_root = (gfloat)xevent->mouse.rootx;
+         event->motion.y_root = (gfloat)xevent->mouse.rooty;
+      event->motion.pressure = 0.5;
+      event->motion.xtilt = 0;
+      event->motion.ytilt = 0;
+      event->motion.state = gr_mod_to_gdk(xevent->mouse.modifiers, xevent->mouse.buttons);
+      event->motion.is_hint = 0;
+      event->motion.source = GDK_SOURCE_MOUSE;
+      event->motion.deviceid = GDK_CORE_POINTER;
+      
+      break;
+    case GR_EVENT_TYPE_MOUSE_POSITION:
+      return_val = FALSE;
+      break;
+    case GR_EVENT_TYPE_MOUSE_ENTER:
+      event->crossing.type = GDK_ENTER_NOTIFY;
+      event->crossing.window = window;
+      event->crossing.subwindow = NULL;
+      event->crossing.time = serial_value++;
+      event->crossing.detail = GDK_NOTIFY_UNKNOWN;
+      //g_message("subwindow 1: %p", event->crossing.subwindow);
+      /* other stuff here , x, y, x_root, y_root */
+      break;
+    case GR_EVENT_TYPE_MOUSE_EXIT:
+      event->crossing.type = GDK_LEAVE_NOTIFY;
+      event->crossing.window = window;
+      event->crossing.subwindow = NULL;
+      event->crossing.time = serial_value++;
+      event->crossing.mode = GDK_CROSSING_NORMAL;
+      event->crossing.detail = GDK_NOTIFY_UNKNOWN;
+      //g_message("subwindow 2: %p", event->crossing.subwindow);
+      /* other stuff here , x, y, x_root, y_root */
+      break;
+    case GR_EVENT_TYPE_FOCUS_IN:
+    case GR_EVENT_TYPE_FOCUS_OUT:
+         event->focus_change.type = GDK_FOCUS_CHANGE;
+         event->focus_change.window = window;
+         event->focus_change.in = (xevent->general.type == GR_EVENT_TYPE_FOCUS_IN);
+
+      break;
+    case GR_EVENT_TYPE_UPDATE:
+    case GR_EVENT_TYPE_CHLD_UPDATE:
+      if (xevent->update.utype == GR_UPDATE_MAP) {
+        event->any.type = GDK_MAP;
+        event->any.window = window;
+      
+      } else if (xevent->update.utype == GR_UPDATE_UNMAP) {
+        event->any.type = GDK_UNMAP;
+        event->any.window = window;
+      
+        if (gdk_xgrab_window == window_private)
+         gdk_xgrab_window = NULL;
+      } else {
+      if (!window || GDK_DRAWABLE_TYPE (window) == GDK_WINDOW_CHILD)
+       return_val = FALSE;
+      else
+       {
+         event->configure.type = GDK_CONFIGURE;
+         event->configure.window = window;
+         event->configure.width = xevent->update.width;
+         event->configure.height = xevent->update.height;
+         event->configure.x = xevent->update.x;
+         event->configure.y = xevent->update.y;
+         window_private->x = event->configure.x;
+         window_private->y = event->configure.y;
+         window_private->drawable.width = event->configure.width;
+         window_private->drawable.height = event->configure.height;
+         if (window_private->resize_count > 1)
+           window_private->resize_count -= 1;
+       }
+      }
+      break;
+    case GR_EVENT_TYPE_EXPOSURE:
+
+      event->expose.type = GDK_EXPOSE;
+      event->expose.window = window;
+      event->expose.area.x = xevent->exposure.x;
+      event->expose.area.y = xevent->exposure.y;
+      event->expose.area.width = xevent->exposure.width;
+      event->expose.area.height = xevent->exposure.height;
+      event->expose.count = 0;
+      
+      break;
+    case GR_EVENT_TYPE_FDINPUT:
+    case GR_EVENT_TYPE_NONE:
+      return_val = FALSE;
+      break;
+    default:
+      return_val = FALSE;
+      g_message("event %d not handled\n", xevent->type);
+  }
+  if (return_val)
+    {
+      if (event->any.window)
+       gdk_window_ref (event->any.window);
+      if (((event->any.type == GDK_ENTER_NOTIFY) ||
+          (event->any.type == GDK_LEAVE_NOTIFY)) &&
+         (event->crossing.subwindow != NULL))
+       gdk_window_ref (event->crossing.subwindow);
+    }
+  else
+    {
+      /* Mark this event as having no resources to be freed */
+      event->any.window = NULL;
+      event->any.type = GDK_NOTHING;
+    }
+  
+  if (window)
+    gdk_window_unref (window);
+  
+  return return_val;
+}
+
+void
+gdk_events_queue (void)
+{
+  GList *node;
+  GdkEvent *event;
+  GR_EVENT xevent;
+
+  while (!gdk_event_queue_find_first())
+    {
+      GrCheckNextEvent (&xevent);
+      if (!xevent.type)
+             return;
+      
+      event = gdk_event_new ();
+      
+      event->any.type = GDK_NOTHING;
+      event->any.window = NULL;
+      event->any.send_event = FALSE;
+
+      ((GdkEventPrivate *)event)->flags |= GDK_EVENT_PENDING;
+
+      gdk_event_queue_append (event);
+      node = gdk_queued_tail;
+
+      if (gdk_event_translate (event, &xevent))
+       {
+         ((GdkEventPrivate *)event)->flags &= ~GDK_EVENT_PENDING;
+         //g_message("got event: %d", event->type);
+       }
+      else
+       {
+         gdk_event_queue_remove_link (node);
+         g_list_free_1 (node);
+         gdk_event_free (event);
+       }
+    }
+}
+
+gboolean
+gdk_event_send_client_message (GdkEvent *event, guint32 xid)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+  return 0;
+}
+
+void
+gdk_event_send_clientmessage_toall (GdkEvent *event)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+}
+
+void
+gdk_flush (void)
+{
+  GrFlush();
+}
+
+
diff --git a/gdk/nanox/gdkfont-nanox.c b/gdk/nanox/gdkfont-nanox.c
new file mode 100644 (file)
index 0000000..19818b5
--- /dev/null
@@ -0,0 +1,146 @@
+#include "gdk.h"
+#include "gdkprivate-nanox.h"
+
+static GR_GC_ID  gc_for_width = 0;
+
+#define ENSURE_GC if (!gc_for_width) gc_for_width = GrNewGC();
+
+GdkFont*
+gdk_font_load (const gchar *font_name)
+{
+  GdkFont *font;
+  GdkFontPrivateX *private;
+  GR_FONTID xfont;
+
+  g_return_val_if_fail (font_name != NULL, NULL);
+
+  xfont = GrCreateFont("System", 0, 0);
+  if (xfont == 0)
+    return NULL;
+
+    {
+      private = g_new (GdkFontPrivateX, 1);
+      private->xfont = xfont;
+      private->base.ref_count = 1;
+      font = (GdkFont*) private;
+      font->type = GDK_FONT_FONT;
+      font->ascent =  8;
+      font->descent = 4;
+
+    }
+
+  return font;
+}
+
+GdkFont*
+gdk_fontset_load (const gchar *fontset_name)
+{
+  return gdk_font_load(fontset_name);
+}
+
+void
+_gdk_font_destroy (GdkFont *font)
+{
+  GrUnloadFont(GDK_FONT_XFONT(font));
+}
+
+gint
+_gdk_font_strlen (GdkFont     *font,
+                 const gchar *str)
+{
+  return strlen(str);
+}
+
+gint
+gdk_font_id (const GdkFont *font)
+{
+  return GDK_FONT_XFONT(font);
+}
+
+gboolean
+gdk_font_equal (const GdkFont *fonta,
+                const GdkFont *fontb)
+{
+  return GDK_FONT_XFONT(fonta) == GDK_FONT_XFONT(fontb);
+}
+
+gint
+gdk_text_width (GdkFont      *font,
+               const gchar  *text,
+               gint          text_length)
+{
+  gint width, height, base;
+  ENSURE_GC;
+  GrSetGCFont(gc_for_width, GDK_FONT_XFONT(font));
+  GrGetGCTextSize(gc_for_width, text, text_length, TF_UTF8, &width, &height, &base);
+  return width;
+}
+
+gint
+gdk_text_width_wc (GdkFont       *font,
+                  const GdkWChar *text,
+                  gint            text_length)
+{
+  gint width, height, base;
+  ENSURE_GC;
+  GrSetGCFont(gc_for_width, GDK_FONT_XFONT(font));
+  GrGetGCTextSize(gc_for_width, text, text_length, TF_UC32, &width, &height, &base);
+  return width;
+}
+
+
+void
+gdk_text_extents (GdkFont     *font,
+                  const gchar *text,
+                  gint         text_length,
+                 gint        *lbearing,
+                 gint        *rbearing,
+                 gint        *width,
+                 gint        *ascent,
+                 gint        *descent)
+{
+  gint mwidth, height, base;
+  ENSURE_GC;
+  GrSetGCFont(gc_for_width, GDK_FONT_XFONT(font));
+  GrGetGCTextSize(gc_for_width, text, text_length, TF_UTF8, &mwidth, &height, &base);
+  if (width)
+       *width = mwidth;
+  if (lbearing)
+       *lbearing = 0;
+  if (rbearing)
+       *rbearing = 0;
+  if (ascent)
+       *ascent = base;
+  if (descent)
+       *descent = height - base;
+
+}
+
+void
+gdk_text_extents_wc (GdkFont        *font,
+                    const GdkWChar *text,
+                    gint            text_length,
+                    gint           *lbearing,
+                    gint           *rbearing,
+                    gint           *width,
+                    gint           *ascent,
+                    gint           *descent)
+{
+  gint mwidth, height, base;
+  ENSURE_GC;
+  GrSetGCFont(gc_for_width, GDK_FONT_XFONT(font));
+  GrGetGCTextSize(gc_for_width, text, text_length, TF_UC32, &mwidth, &height, &base);
+  if (width)
+       *width = mwidth;
+  if (lbearing)
+       *lbearing = 0;
+  if (rbearing)
+       *rbearing = 0;
+  if (ascent)
+       *ascent = base;
+  if (descent)
+       *descent = height - base;
+}
+
+
diff --git a/gdk/nanox/gdkgc-nanox.c b/gdk/nanox/gdkgc-nanox.c
new file mode 100644 (file)
index 0000000..78246a3
--- /dev/null
@@ -0,0 +1,103 @@
+#include "gdkprivate-nanox.h"
+
+static void gdk_nanox_gc_destroy    (GdkGC           *gc);
+static void gdk_nanox_gc_get_values (GdkGC           *gc,
+                                  GdkGCValues     *values);
+static void gdk_nanox_gc_set_values (GdkGC           *gc,
+                                  GdkGCValues     *values,
+                                  GdkGCValuesMask  values_mask);
+static void gdk_nanox_gc_set_dashes (GdkGC           *gc,
+                                  gint             dash_offset,
+                                  gchar            dash_list[],
+                                  gint             n);
+
+static GdkGCClass gdk_nanox_gc_class = {
+  gdk_nanox_gc_destroy,
+  gdk_nanox_gc_get_values,
+  gdk_nanox_gc_set_values,
+  gdk_nanox_gc_set_dashes
+};
+
+GdkGC *
+_gdk_nanox_gc_new (GdkDrawable      *drawable,
+                GdkGCValues      *values,
+                GdkGCValuesMask   values_mask)
+{
+       
+  GdkGC *gc;
+  GdkGCPrivate *private;
+  
+  gc = gdk_gc_alloc ();
+  private = (GdkGCPrivate *)gc;
+
+  private->klass = &gdk_nanox_gc_class;
+  private->klass_data = g_new (GdkGCXData, 1);
+
+  GDK_GC_XDATA(gc)->xgc = GrNewGC();
+  GrSetGCUseBackground(GDK_GC_XDATA(gc)->xgc, 0);
+  GrSetGCForeground(GDK_GC_XDATA(gc)->xgc, RGB2PIXEL(0,0,0));
+  GrSetGCBackground(GDK_GC_XDATA(gc)->xgc, RGB2PIXEL(0,0,0));
+  g_message("created GC: %d", GDK_GC_XDATA(gc)->xgc);
+  return gc;
+}
+
+
+static void
+gdk_nanox_gc_destroy (GdkGC *gc)
+{
+  GrDestroyGC (GDK_GC_XGC (gc));
+  g_free (GDK_GC_XDATA (gc));
+}
+
+static void
+gdk_nanox_gc_get_values (GdkGC       *gc,
+                      GdkGCValues *values)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+}
+
+
+static void
+gdk_nanox_gc_set_values (GdkGC           *gc,
+                      GdkGCValues     *values,
+                      GdkGCValuesMask  values_mask)
+{
+       if (values_mask & GDK_GC_FOREGROUND)
+         GrSetGCForeground(GDK_GC_XGC(gc), values->foreground.pixel);
+       else if (values_mask & GDK_GC_BACKGROUND)
+         GrSetGCBackground(GDK_GC_XGC(gc), values->background.pixel);
+       else if (values_mask & GDK_GC_FONT)
+         GrSetGCFont(GDK_GC_XGC(gc), GDK_FONT_XFONT(values->font));
+}
+
+static void
+gdk_nanox_gc_set_dashes (GdkGC *gc,
+                      gint   dash_offset,
+                      gchar  dash_list[],
+                      gint   n)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+}
+
+void
+gdk_gc_set_clip_rectangle (GdkGC       *gc,
+                          GdkRectangle *rectangle)
+{
+               //g_message("unimplemented %s", __FUNCTION__);
+}
+
+void
+gdk_gc_set_clip_region (GdkGC           *gc,
+                       GdkRegion        *region)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+}
+
+
+void
+gdk_gc_copy (GdkGC *dst_gc, GdkGC *src_gc)
+{
+  GDK_GC_XDATA(dst_gc)->xgc = GrCopyGC(GDK_GC_XGC(src_gc));
+}
+
+
diff --git a/gdk/nanox/gdkglobals-nanox.c b/gdk/nanox/gdkglobals-nanox.c
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/gdk/nanox/gdkim-nanox.c b/gdk/nanox/gdkim-nanox.c
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/gdk/nanox/gdkimage-nanox.c b/gdk/nanox/gdkimage-nanox.c
new file mode 100644 (file)
index 0000000..e0b580a
--- /dev/null
@@ -0,0 +1,118 @@
+#include "gdk.h"
+#include "gdkprivate-nanox.h"
+
+static void
+gdk_nanox_image_destroy (GdkImage *image);
+
+static void
+gdk_image_put_normal (GdkImage    *image,
+                     GdkDrawable *drawable,
+                     GdkGC       *gc,
+                     gint         xsrc,
+                     gint         ysrc,
+                     gint         xdest,
+                     gint         ydest,
+                     gint         width,
+                     gint         height);
+
+static GdkImageClass image_class_normal = {
+  gdk_nanox_image_destroy,
+  gdk_image_put_normal
+};
+
+void
+gdk_image_exit (void)
+{
+}
+
+
+GdkImage *
+gdk_image_new_bitmap(GdkVisual *visual, gpointer data, gint w, gint h)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+  return NULL;
+}
+
+void
+gdk_image_init (void)
+{
+}
+
+
+GdkImage*
+gdk_image_new (GdkImageType  type,
+              GdkVisual    *visual,
+              gint          width,
+              gint          height)
+{
+  GdkImage *image;
+  GdkImagePrivateX *private;
+
+  private = g_new (GdkImagePrivateX, 1);
+  image = (GdkImage*) private;
+
+  private->base.ref_count = 1;
+  image->type = type;
+  image->visual = visual;
+  image->width = width;
+  image->height = height;
+  image->depth = visual->depth;
+  
+  private->base.klass = &image_class_normal;
+  //private->ximage = NULL;
+  /* more: implement as a pixmap? */
+  return image;
+}
+
+
+GdkImage*
+gdk_image_get (GdkWindow *window,
+              gint       x,
+              gint       y,
+              gint       width,
+              gint       height)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+  return NULL;
+}
+
+
+guint32
+gdk_image_get_pixel (GdkImage *image,
+                    gint x,
+                    gint y)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+  return 0;
+}
+
+void
+gdk_image_put_pixel (GdkImage *image,
+                    gint x,
+                    gint y,
+                    guint32 pixel)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+}
+
+
+static void
+gdk_nanox_image_destroy (GdkImage *image)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+}
+
+static void
+gdk_image_put_normal (GdkImage    *image,
+                     GdkDrawable *drawable,
+                     GdkGC       *gc,
+                     gint         xsrc,
+                     gint         ysrc,
+                     gint         xdest,
+                     gint         ydest,
+                     gint         width,
+                     gint         height)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+}
+
diff --git a/gdk/nanox/gdkinput-none.c b/gdk/nanox/gdkinput-none.c
new file mode 100644 (file)
index 0000000..d3aba3d
--- /dev/null
@@ -0,0 +1,79 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "gdkinputprivate.h"
+
+/*
+ * Modified by the GTK+ Team and others 1997-1999.  See the AUTHORS
+ * file for a list of people on the GTK+ Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
+ */
+
+static void gdk_input_none_get_pointer (GdkWindow       *window,
+                                       guint32   deviceid,
+                                       gdouble         *x,
+                                       gdouble         *y,
+                                       gdouble         *pressure,
+                                       gdouble         *xtilt,
+                                       gdouble         *ytilt,
+                                       GdkModifierType *mask);
+
+void
+gdk_input_init (void)
+{
+  gdk_input_vtable.set_mode           = NULL;
+  gdk_input_vtable.set_axes           = NULL;
+  gdk_input_vtable.set_key            = NULL;
+  gdk_input_vtable.motion_events      = NULL;
+  gdk_input_vtable.get_pointer        = gdk_input_none_get_pointer;
+  gdk_input_vtable.grab_pointer       = NULL;
+  gdk_input_vtable.ungrab_pointer     = NULL;
+  gdk_input_vtable.configure_event    = NULL;
+  gdk_input_vtable.enter_event        = NULL;
+  gdk_input_vtable.other_event        = NULL;
+  gdk_input_vtable.window_none_event  = NULL;
+  gdk_input_vtable.enable_window      = NULL;
+  gdk_input_vtable.disable_window     = NULL;
+
+  gdk_input_devices = g_list_append (NULL, (GdkDeviceInfo *) &gdk_input_core_info);
+
+  gdk_input_ignore_core = FALSE;
+}
+
+static void
+gdk_input_none_get_pointer (GdkWindow       *window,
+                           guint32          deviceid,
+                           gdouble         *x,
+                           gdouble         *y,
+                           gdouble         *pressure,
+                           gdouble         *xtilt,
+                           gdouble         *ytilt,
+                           GdkModifierType *mask)
+{
+  gint x_int, y_int;
+
+  gdk_window_get_pointer (window, &x_int, &y_int, mask);
+
+  if (x) *x = x_int;
+  if (y) *y = y_int;
+  if (pressure) *pressure = 0.5;
+  if (xtilt) *xtilt = 0;
+  if (ytilt) *ytilt = 0;
+}
diff --git a/gdk/nanox/gdkinput.c b/gdk/nanox/gdkinput.c
new file mode 100644 (file)
index 0000000..6dd0195
--- /dev/null
@@ -0,0 +1,282 @@
+#include "gdk.h"
+#include "gdkprivate-nanox.h"
+#include "gdkinputprivate.h"
+
+static const GdkAxisUse gdk_input_core_axes[] = { GDK_AXIS_X, GDK_AXIS_Y };
+
+const GdkDeviceInfo gdk_input_core_info =
+{
+  GDK_CORE_POINTER,
+  "Core Pointer",
+  GDK_SOURCE_MOUSE,
+  GDK_MODE_SCREEN,
+  TRUE,
+  2,
+  gdk_input_core_axes
+};
+
+/* Global variables  */
+
+GdkInputVTable    gdk_input_vtable;
+/* information about network port and host for gxid daemon */
+gchar            *gdk_input_gxid_host;
+gint              gdk_input_gxid_port;
+gint              gdk_input_ignore_core;
+
+GList            *gdk_input_devices;
+GList            *gdk_input_windows;
+
+GList *
+gdk_input_list_devices (void)
+{
+  return gdk_input_devices;
+}
+
+void
+gdk_input_set_source (guint32 deviceid, GdkInputSource source)
+{
+  GdkDevicePrivate *gdkdev = gdk_input_find_device(deviceid);
+  g_return_if_fail (gdkdev != NULL);
+
+  gdkdev->info.source = source;
+}
+
+gboolean
+gdk_input_set_mode (guint32 deviceid, GdkInputMode mode)
+{
+  if (deviceid == GDK_CORE_POINTER)
+    return FALSE;
+
+  if (gdk_input_vtable.set_mode)
+    return gdk_input_vtable.set_mode(deviceid,mode);
+  else
+    return FALSE;
+}
+
+void
+gdk_input_set_axes (guint32 deviceid, GdkAxisUse *axes)
+{
+  if (deviceid != GDK_CORE_POINTER && gdk_input_vtable.set_axes)
+    gdk_input_vtable.set_axes (deviceid, axes);
+}
+
+void gdk_input_set_key (guint32 deviceid,
+                       guint   index,
+                       guint   keyval,
+                       GdkModifierType modifiers)
+{
+  if (deviceid != GDK_CORE_POINTER && gdk_input_vtable.set_key)
+    gdk_input_vtable.set_key (deviceid, index, keyval, modifiers);
+}
+
+GdkTimeCoord *
+gdk_input_motion_events (GdkWindow *window,
+                        guint32 deviceid,
+                        guint32 start,
+                        guint32 stop,
+                        gint *nevents_return)
+{
+  GdkTimeCoord *coords;
+  int i;
+
+  g_return_val_if_fail (window != NULL, NULL);
+  g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
+  
+  if (GDK_DRAWABLE_DESTROYED (window))
+    return NULL;
+
+  if (deviceid == GDK_CORE_POINTER)
+    {
+       return NULL;
+    }
+  else
+    {
+      if (gdk_input_vtable.motion_events)
+       {
+         return gdk_input_vtable.motion_events(window,
+                                               deviceid, start, stop,
+                                               nevents_return);
+       }
+      else
+       {
+         *nevents_return = 0;
+         return NULL;
+       }
+    }
+}
+
+gint
+gdk_input_enable_window (GdkWindow *window, GdkDevicePrivate *gdkdev)
+{
+  if (gdk_input_vtable.enable_window)
+    return gdk_input_vtable.enable_window (window, gdkdev);
+  else
+    return TRUE;
+}
+
+gint
+gdk_input_disable_window (GdkWindow *window, GdkDevicePrivate *gdkdev)
+{
+  if (gdk_input_vtable.disable_window)
+    return gdk_input_vtable.disable_window(window,gdkdev);
+  else
+    return TRUE;
+}
+
+
+GdkInputWindow *
+gdk_input_window_find(GdkWindow *window)
+{
+  GList *tmp_list;
+
+  for (tmp_list=gdk_input_windows; tmp_list; tmp_list=tmp_list->next)
+    if (((GdkInputWindow *)(tmp_list->data))->window == window)
+      return (GdkInputWindow *)(tmp_list->data);
+
+  return NULL;      /* Not found */
+}
+
+/* FIXME: this routine currently needs to be called between creation
+   and the corresponding configure event (because it doesn't get the
+   root_relative_geometry).  This should work with
+   gtk_window_set_extension_events, but will likely fail in other
+   cases */
+
+void
+gdk_input_set_extension_events (GdkWindow *window, gint mask,
+                               GdkExtensionMode mode)
+{
+  GdkWindowPrivate *window_private;
+  GList *tmp_list;
+  GdkInputWindow *iw;
+
+  g_return_if_fail (window != NULL);
+  g_return_if_fail (GDK_IS_WINDOW (window));
+
+  window_private = (GdkWindowPrivate*) window;
+  if (GDK_DRAWABLE_DESTROYED (window))
+    return;
+
+  if (mode == GDK_EXTENSION_EVENTS_NONE)
+    mask = 0;
+
+  if (mask != 0)
+    {
+      iw = g_new(GdkInputWindow,1);
+
+      iw->window = window;
+      iw->mode = mode;
+
+      iw->obscuring = NULL;
+      iw->num_obscuring = 0;
+      iw->grabbed = FALSE;
+
+      gdk_input_windows = g_list_append(gdk_input_windows,iw);
+      window_private->extension_events = mask;
+
+      /* Add enter window events to the event mask */
+      /* FIXME, this is not needed for XINPUT_NONE */
+      gdk_window_set_events (window,
+                            gdk_window_get_events (window) | 
+                            GDK_ENTER_NOTIFY_MASK);
+    }
+  else
+    {
+      iw = gdk_input_window_find (window);
+      if (iw)
+       {
+         gdk_input_windows = g_list_remove(gdk_input_windows,iw);
+         g_free(iw);
+       }
+
+      window_private->extension_events = 0;
+    }
+
+  for (tmp_list = gdk_input_devices; tmp_list; tmp_list = tmp_list->next)
+    {
+      GdkDevicePrivate *gdkdev = (GdkDevicePrivate *)(tmp_list->data);
+
+      if (gdkdev->info.deviceid != GDK_CORE_POINTER)
+       {
+         if (mask != 0 && gdkdev->info.mode != GDK_MODE_DISABLED
+             && (gdkdev->info.has_cursor || mode == GDK_EXTENSION_EVENTS_ALL))
+           gdk_input_enable_window(window,gdkdev);
+         else
+           gdk_input_disable_window(window,gdkdev);
+       }
+    }
+}
+
+void
+gdk_input_window_destroy (GdkWindow *window)
+{
+  GdkInputWindow *input_window;
+
+  input_window = gdk_input_window_find (window);
+  g_return_if_fail (input_window != NULL);
+
+  gdk_input_windows = g_list_remove (gdk_input_windows,input_window);
+  g_free(input_window);
+}
+
+void
+gdk_input_exit (void)
+{
+  GList *tmp_list;
+  GdkDevicePrivate *gdkdev;
+
+  for (tmp_list = gdk_input_devices; tmp_list; tmp_list = tmp_list->next)
+    {
+      gdkdev = (GdkDevicePrivate *)(tmp_list->data);
+      if (gdkdev->info.deviceid != GDK_CORE_POINTER)
+       {
+         gdk_input_set_mode(gdkdev->info.deviceid,GDK_MODE_DISABLED);
+
+         g_free(gdkdev->info.name);
+#ifndef XINPUT_NONE      
+         g_free(gdkdev->axes);
+#endif   
+         g_free(gdkdev->info.axes);
+         g_free(gdkdev->info.keys);
+         g_free(gdkdev);
+       }
+    }
+
+  g_list_free(gdk_input_devices);
+
+  for (tmp_list = gdk_input_windows; tmp_list; tmp_list = tmp_list->next)
+    {
+      g_free(tmp_list->data);
+    }
+  g_list_free(gdk_input_windows);
+}
+
+GdkDevicePrivate *
+gdk_input_find_device(guint32 id)
+{
+  GList *tmp_list = gdk_input_devices;
+  GdkDevicePrivate *gdkdev;
+  while (tmp_list)
+    {
+      gdkdev = (GdkDevicePrivate *)(tmp_list->data);
+      if (gdkdev->info.deviceid == id)
+       return gdkdev;
+      tmp_list = tmp_list->next;
+    }
+  return NULL;
+}
+
+void
+gdk_input_window_get_pointer (GdkWindow       *window,
+                             guint32     deviceid,
+                             gdouble         *x,
+                             gdouble         *y,
+                             gdouble         *pressure,
+                             gdouble         *xtilt,
+                             gdouble         *ytilt,
+                             GdkModifierType *mask)
+{
+  if (gdk_input_vtable.get_pointer)
+    gdk_input_vtable.get_pointer (window, deviceid, x, y, pressure,
+                                 xtilt, ytilt, mask);
+}
diff --git a/gdk/nanox/gdkmain-nanox.c b/gdk/nanox/gdkmain-nanox.c
new file mode 100644 (file)
index 0000000..2892940
--- /dev/null
@@ -0,0 +1,250 @@
+#include "gdk.h"
+#include "gdkinternals.h"
+#include "gdkprivate-nanox.h"
+
+static GR_SCREEN_INFO screen_info;
+static int gdk_use_xshm = 0; /* shm not supported */
+guint gdk_selection_property = 0;
+gchar* gdk_progclass = NULL;
+GdkWindowPrivate* gdk_xgrab_window = NULL;
+
+GdkArgDesc _gdk_windowing_args[] = {
+  {NULL}
+};
+
+gboolean
+_gdk_windowing_init_check (int argc, char **argv)
+{
+  int result = GrOpen();
+  if (result < 0)
+       return 0;
+  GrGetScreenInfo(&screen_info);
+
+  return 1;
+}
+
+
+gchar*
+gdk_set_locale (void)
+{
+       return "";
+}
+
+void
+gdk_set_use_xshm (gboolean use_xshm)
+{
+  gdk_use_xshm = 0; /* shm not supported */
+}
+
+gboolean
+gdk_get_use_xshm (void)
+{
+  return gdk_use_xshm;
+}
+
+gint
+gdk_pointer_grab (GdkWindow *    window,
+                 gboolean        owner_events,
+                 GdkEventMask    event_mask,
+                 GdkWindow *     confine_to,
+                 GdkCursor *     cursor,
+                 guint32         time)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+  return 0;
+}
+
+
+void
+gdk_pointer_ungrab (guint32 time)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+}
+
+
+gboolean
+gdk_pointer_is_grabbed (void)
+{
+  return gdk_xgrab_window != NULL;
+}
+
+gint
+gdk_keyboard_grab (GdkWindow *    window,
+                  gboolean        owner_events,
+                  guint32         time)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+  return 0;
+}
+
+
+void
+gdk_keyboard_ungrab (guint32 time)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+}
+
+gint
+gdk_screen_width (void)
+{
+  return screen_info.cols;
+}
+
+gint
+gdk_screen_height (void)
+{
+  return screen_info.rows;
+}
+
+gint
+gdk_screen_width_mm (void)
+{
+  return screen_info.cols*10/screen_info.xdpcm; 
+}
+
+gint
+gdk_screen_height_mm (void)
+{
+  return screen_info.rows*10/screen_info.ydpcm; 
+}
+
+void
+gdk_set_sm_client_id (const gchar* sm_client_id)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+}
+
+
+void
+gdk_key_repeat_disable (void)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+}
+
+void
+gdk_key_repeat_restore (void)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+}
+
+void
+gdk_beep (void)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+}
+
+void
+gdk_windowing_exit (void)
+{
+  GrClose();
+}
+
+gchar *
+gdk_get_display (void)
+{
+  return "nano-X";
+}
+
+gchar*
+gdk_keyval_name (guint       keyval)
+{
+       static gchar buf[64];
+       g_snprintf(buf, 64, "%c", keyval);
+       return buf;
+}
+
+guint
+gdk_keyval_from_name (const gchar *keyval_name)
+{
+  return *keyval_name;
+}
+
+/*
+void
+gdk_keyval_convert_case (guint symbol,
+                        guint *lower,
+                        guint *upper)
+{
+}
+*/
+
+static guint gdk_xid_hash    (guint *xid);
+static gint  gdk_xid_compare (guint *a,
+                             guint *b);
+
+
+static GHashTable *xid_ht = NULL;
+
+
+void
+gdk_xid_table_insert (guint      *xid,
+                     gpointer  data)
+{
+  g_return_if_fail (xid != NULL);
+
+  if (!xid_ht)
+    xid_ht = g_hash_table_new ((GHashFunc) gdk_xid_hash,
+                              (GCompareFunc) gdk_xid_compare);
+
+  g_hash_table_insert (xid_ht, xid, data);
+}
+
+void
+gdk_xid_table_remove (guint xid)
+{
+  if (!xid_ht)
+    xid_ht = g_hash_table_new ((GHashFunc) gdk_xid_hash,
+                              (GCompareFunc) gdk_xid_compare);
+
+  g_hash_table_remove (xid_ht, &xid);
+}
+
+gpointer
+gdk_xid_table_lookup (guint xid)
+{
+  gpointer data = NULL;
+
+  if (xid_ht)
+    data = g_hash_table_lookup (xid_ht, &xid);
+  
+  return data;
+}
+
+
+static guint
+gdk_xid_hash (guint *xid)
+{
+  return *xid;
+}
+
+static gint
+gdk_xid_compare (guint *a,
+                guint *b)
+{
+  return (*a == *b);
+}
+
+gchar *
+gdk_wcstombs (const GdkWChar *src)
+{
+  gchar *mbstr;
+  gint i, length = 0;
+
+  while (src[length] != 0)
+       length++;
+  mbstr = g_new (gchar, length + 1);
+  for (i=0; i <length+1;++i)
+       mbstr[i] = src[i];
+  return mbstr;
+}
+
+gint
+gdk_mbstowcs (GdkWChar *dest, const gchar *src, gint dest_max)
+{
+  gint i;
+
+  for (i=0; i < dest_max && src[i]; i++)
+       dest[i] = src[i];
+  return i;
+}
+
diff --git a/gdk/nanox/gdkpixmap-nanox.c b/gdk/nanox/gdkpixmap-nanox.c
new file mode 100644 (file)
index 0000000..3235acf
--- /dev/null
@@ -0,0 +1,149 @@
+#include "gdk.h"
+#include "gdkprivate-nanox.h"
+
+GdkDrawableClass _gdk_nanox_pixmap_class;
+
+static void
+gdk_nanox_pixmap_destroy (GdkPixmap *pixmap)
+{
+  GrDestroyWindow (GDK_DRAWABLE_XID (pixmap));
+  gdk_xid_table_remove (GDK_DRAWABLE_XID (pixmap));
+
+  g_free (GDK_DRAWABLE_XDATA (pixmap));
+}
+
+static GdkDrawable *
+gdk_nanox_pixmap_alloc (void)
+{
+  GdkDrawable *drawable;
+  GdkDrawablePrivate *private;
+  
+  static GdkDrawableClass klass;
+  static gboolean initialized = FALSE;
+
+  if (!initialized)
+    {
+      initialized = TRUE;
+      
+      klass = _gdk_nanox_drawable_class;
+      klass.destroy = gdk_nanox_pixmap_destroy;
+    }
+
+  drawable = gdk_drawable_alloc ();
+  private = (GdkDrawablePrivate *)drawable;
+
+  private->klass = &klass;
+  private->klass_data = g_new (GdkDrawableXData, 1);
+  private->window_type = GDK_DRAWABLE_PIXMAP;
+
+  return drawable;
+}
+
+GdkPixmap*
+gdk_pixmap_new (GdkWindow *window,
+               gint       width,
+               gint       height,
+               gint       depth)
+{
+  GdkPixmap *pixmap;
+  GdkDrawablePrivate *private;
+
+  g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
+  g_return_val_if_fail ((window != NULL) || (depth != -1), NULL);
+  g_return_val_if_fail ((width != 0) && (height != 0), NULL);
+  
+  if (!window)
+    window = gdk_parent_root;
+
+  if (GDK_DRAWABLE_DESTROYED (window))
+    return NULL;
+
+  if (depth == -1)
+    depth = gdk_drawable_get_visual (window)->depth;
+
+  pixmap = gdk_nanox_pixmap_alloc ();
+  private = (GdkDrawablePrivate *)pixmap;
+
+  GDK_DRAWABLE_XDATA (private)->xid = GrNewPixmap (width, height, NULL);
+  private->width = width;
+  private->height = height;
+
+  gdk_xid_table_insert (&GDK_DRAWABLE_XID (pixmap), pixmap);
+
+  return pixmap;
+}
+
+GdkPixmap *
+gdk_bitmap_create_from_data (GdkWindow   *window,
+                            const gchar *data,
+                            gint         width,
+                            gint         height)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+  return NULL;
+}
+
+GdkPixmap*
+gdk_pixmap_create_from_data (GdkWindow   *window,
+                            const gchar *data,
+                            gint         width,
+                            gint         height,
+                            gint         depth,
+                            GdkColor    *fg,
+                            GdkColor    *bg)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+  return NULL;
+}
+
+
+GdkPixmap*
+gdk_pixmap_colormap_create_from_xpm (GdkWindow   *window,
+                                    GdkColormap *colormap,
+                                    GdkBitmap  **mask,
+                                    GdkColor    *transparent_color,
+                                    const gchar *filename)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+  return NULL;
+}
+
+
+GdkPixmap*
+gdk_pixmap_create_from_xpm (GdkWindow  *window,
+                           GdkBitmap **mask,
+                           GdkColor   *transparent_color,
+                           const gchar *filename)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+  return NULL;
+}
+
+GdkPixmap*
+gdk_pixmap_colormap_create_from_xpm_d (GdkWindow  *window,
+                                      GdkColormap *colormap,
+                                      GdkBitmap **mask,
+                                      GdkColor   *transparent_color,
+                                      gchar     **data)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+  return NULL;
+}
+
+GdkPixmap*
+gdk_pixmap_create_from_xpm_d (GdkWindow  *window,
+                             GdkBitmap **mask,
+                             GdkColor   *transparent_color,
+                             gchar     **data)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+  return NULL;
+}
+
+GdkPixmap*
+gdk_pixmap_foreign_new (guint32 anid)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+  return NULL;
+}
+
diff --git a/gdk/nanox/gdkpolyreg-generic.c b/gdk/nanox/gdkpolyreg-generic.c
new file mode 100644 (file)
index 0000000..b98bd56
--- /dev/null
@@ -0,0 +1,616 @@
+/* $TOG: PolyReg.c /main/15 1998/02/06 17:47:08 kaleb $ */
+/************************************************************************
+
+Copyright 1987, 1998  The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its 
+documentation for any purpose and without fee is hereby granted, 
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in 
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+************************************************************************/
+/* $XFree86: xc/lib/X11/PolyReg.c,v 1.4 1998/10/03 08:41:21 dawes Exp $ */
+
+#define LARGE_COORDINATE 1000000
+#define SMALL_COORDINATE -LARGE_COORDINATE
+
+#include <gdkregion.h>
+#include "gdkregion-generic.h"
+#include "gdkpoly-generic.h"
+
+/*
+ *     InsertEdgeInET
+ *
+ *     Insert the given edge into the edge table.
+ *     First we must find the correct bucket in the
+ *     Edge table, then find the right slot in the
+ *     bucket.  Finally, we can insert it.
+ *
+ */
+static void
+InsertEdgeInET(ET, ETE, scanline, SLLBlock, iSLLBlock)
+    EdgeTable *ET;
+    EdgeTableEntry *ETE;
+    int scanline;
+    ScanLineListBlock **SLLBlock;
+    int *iSLLBlock;
+{
+    EdgeTableEntry *start, *prev;
+    ScanLineList *pSLL, *pPrevSLL;
+    ScanLineListBlock *tmpSLLBlock;
+
+    /*
+     * find the right bucket to put the edge into
+     */
+    pPrevSLL = &ET->scanlines;
+    pSLL = pPrevSLL->next;
+    while (pSLL && (pSLL->scanline < scanline)) 
+    {
+        pPrevSLL = pSLL;
+        pSLL = pSLL->next;
+    }
+
+    /*
+     * reassign pSLL (pointer to ScanLineList) if necessary
+     */
+    if ((!pSLL) || (pSLL->scanline > scanline)) 
+    {
+        if (*iSLLBlock > SLLSPERBLOCK-1) 
+        {
+            tmpSLLBlock = 
+                 (ScanLineListBlock *)g_malloc(sizeof(ScanLineListBlock));
+            (*SLLBlock)->next = tmpSLLBlock;
+            tmpSLLBlock->next = (ScanLineListBlock *)NULL;
+            *SLLBlock = tmpSLLBlock;
+            *iSLLBlock = 0;
+        }
+        pSLL = &((*SLLBlock)->SLLs[(*iSLLBlock)++]);
+
+        pSLL->next = pPrevSLL->next;
+        pSLL->edgelist = (EdgeTableEntry *)NULL;
+        pPrevSLL->next = pSLL;
+    }
+    pSLL->scanline = scanline;
+
+    /*
+     * now insert the edge in the right bucket
+     */
+    prev = (EdgeTableEntry *)NULL;
+    start = pSLL->edgelist;
+    while (start && (start->bres.minor_axis < ETE->bres.minor_axis)) 
+    {
+        prev = start;
+        start = start->next;
+    }
+    ETE->next = start;
+
+    if (prev)
+        prev->next = ETE;
+    else
+        pSLL->edgelist = ETE;
+}
+\f
+/*
+ *     CreateEdgeTable
+ *
+ *     This routine creates the edge table for
+ *     scan converting polygons. 
+ *     The Edge Table (ET) looks like:
+ *
+ *    EdgeTable
+ *     --------
+ *    |  ymax  |        ScanLineLists
+ *    |scanline|-->------------>-------------->...
+ *     --------   |scanline|   |scanline|
+ *                |edgelist|   |edgelist|
+ *                ---------    ---------
+ *                    |             |
+ *                    |             |
+ *                    V             V
+ *              list of ETEs   list of ETEs
+ *
+ *     where ETE is an EdgeTableEntry data structure,
+ *     and there is one ScanLineList per scanline at
+ *     which an edge is initially entered.
+ *
+ */
+
+static void
+CreateETandAET(count, pts, ET, AET, pETEs, pSLLBlock)
+    int count;
+    GdkPoint *pts;
+    EdgeTable *ET;
+    EdgeTableEntry *AET;
+    EdgeTableEntry *pETEs;
+    ScanLineListBlock   *pSLLBlock;
+{
+    GdkPoint *top, *bottom;
+    GdkPoint *PrevPt, *CurrPt;
+    int iSLLBlock = 0;
+    int dy;
+
+    if (count < 2)  return;
+
+    /*
+     *  initialize the Active Edge Table
+     */
+    AET->next = (EdgeTableEntry *)NULL;
+    AET->back = (EdgeTableEntry *)NULL;
+    AET->nextWETE = (EdgeTableEntry *)NULL;
+    AET->bres.minor_axis = SMALL_COORDINATE;
+
+    /*
+     *  initialize the Edge Table.
+     */
+    ET->scanlines.next = (ScanLineList *)NULL;
+    ET->ymax = SMALL_COORDINATE;
+    ET->ymin = LARGE_COORDINATE;
+    pSLLBlock->next = (ScanLineListBlock *)NULL;
+
+    PrevPt = &pts[count-1];
+
+    /*
+     *  for each vertex in the array of points.
+     *  In this loop we are dealing with two vertices at
+     *  a time -- these make up one edge of the polygon.
+     */
+    while (count--) 
+    {
+        CurrPt = pts++;
+
+        /*
+         *  find out which point is above and which is below.
+         */
+        if (PrevPt->y > CurrPt->y) 
+        {
+            bottom = PrevPt, top = CurrPt;
+            pETEs->ClockWise = 0;
+        }
+        else 
+        {
+            bottom = CurrPt, top = PrevPt;
+            pETEs->ClockWise = 1;
+        }
+
+        /*
+         * don't add horizontal edges to the Edge table.
+         */
+        if (bottom->y != top->y) 
+        {
+            pETEs->ymax = bottom->y-1;  /* -1 so we don't get last scanline */
+
+            /*
+             *  initialize integer edge algorithm
+             */
+            dy = bottom->y - top->y;
+            BRESINITPGONSTRUCT(dy, top->x, bottom->x, pETEs->bres);
+
+            InsertEdgeInET(ET, pETEs, top->y, &pSLLBlock, &iSLLBlock);
+
+           if (PrevPt->y > ET->ymax)
+               ET->ymax = PrevPt->y;
+           if (PrevPt->y < ET->ymin)
+               ET->ymin = PrevPt->y;
+            pETEs++;
+        }
+
+        PrevPt = CurrPt;
+    }
+}
+\f
+/*
+ *     loadAET
+ *
+ *     This routine moves EdgeTableEntries from the
+ *     EdgeTable into the Active Edge Table,
+ *     leaving them sorted by smaller x coordinate.
+ *
+ */
+
+static void
+loadAET(AET, ETEs)
+    EdgeTableEntry *AET, *ETEs;
+{
+    EdgeTableEntry *pPrevAET;
+    EdgeTableEntry *tmp;
+
+    pPrevAET = AET;
+    AET = AET->next;
+    while (ETEs) 
+    {
+        while (AET && (AET->bres.minor_axis < ETEs->bres.minor_axis)) 
+        {
+            pPrevAET = AET;
+            AET = AET->next;
+        }
+        tmp = ETEs->next;
+        ETEs->next = AET;
+        if (AET)
+            AET->back = ETEs;
+        ETEs->back = pPrevAET;
+        pPrevAET->next = ETEs;
+        pPrevAET = ETEs;
+
+        ETEs = tmp;
+    }
+}
+\f
+/*
+ *     computeWAET
+ *
+ *     This routine links the AET by the
+ *     nextWETE (winding EdgeTableEntry) link for
+ *     use by the winding number rule.  The final 
+ *     Active Edge Table (AET) might look something
+ *     like:
+ *
+ *     AET
+ *     ----------  ---------   ---------
+ *     |ymax    |  |ymax    |  |ymax    | 
+ *     | ...    |  |...     |  |...     |
+ *     |next    |->|next    |->|next    |->...
+ *     |nextWETE|  |nextWETE|  |nextWETE|
+ *     ---------   ---------   ^--------
+ *         |                   |       |
+ *         V------------------->       V---> ...
+ *
+ */
+static void
+computeWAET(AET)
+    EdgeTableEntry *AET;
+{
+    EdgeTableEntry *pWETE;
+    int inside = 1;
+    int isInside = 0;
+
+    AET->nextWETE = (EdgeTableEntry *)NULL;
+    pWETE = AET;
+    AET = AET->next;
+    while (AET) 
+    {
+        if (AET->ClockWise)
+            isInside++;
+        else
+            isInside--;
+
+        if ((!inside && !isInside) ||
+            ( inside &&  isInside)) 
+        {
+            pWETE->nextWETE = AET;
+            pWETE = AET;
+            inside = !inside;
+        }
+        AET = AET->next;
+    }
+    pWETE->nextWETE = (EdgeTableEntry *)NULL;
+}
+\f
+/*
+ *     InsertionSort
+ *
+ *     Just a simple insertion sort using
+ *     pointers and back pointers to sort the Active
+ *     Edge Table.
+ *
+ */
+
+static int
+InsertionSort(AET)
+    EdgeTableEntry *AET;
+{
+    EdgeTableEntry *pETEchase;
+    EdgeTableEntry *pETEinsert;
+    EdgeTableEntry *pETEchaseBackTMP;
+    int changed = 0;
+
+    AET = AET->next;
+    while (AET) 
+    {
+        pETEinsert = AET;
+        pETEchase = AET;
+        while (pETEchase->back->bres.minor_axis > AET->bres.minor_axis)
+            pETEchase = pETEchase->back;
+
+        AET = AET->next;
+        if (pETEchase != pETEinsert) 
+        {
+            pETEchaseBackTMP = pETEchase->back;
+            pETEinsert->back->next = AET;
+            if (AET)
+                AET->back = pETEinsert->back;
+            pETEinsert->next = pETEchase;
+            pETEchase->back->next = pETEinsert;
+            pETEchase->back = pETEinsert;
+            pETEinsert->back = pETEchaseBackTMP;
+            changed = 1;
+        }
+    }
+    return(changed);
+}
+\f
+/*
+ *     Clean up our act.
+ */
+static void
+FreeStorage(pSLLBlock)
+    ScanLineListBlock   *pSLLBlock;
+{
+    ScanLineListBlock   *tmpSLLBlock;
+
+    while (pSLLBlock) 
+    {
+        tmpSLLBlock = pSLLBlock->next;
+        g_free (pSLLBlock);
+        pSLLBlock = tmpSLLBlock;
+    }
+}
+
+/*
+ *     Create an array of rectangles from a list of points.
+ *     If indeed these things (POINTS, RECTS) are the same,
+ *     then this proc is still needed, because it allocates
+ *     storage for the array, which was allocated on the
+ *     stack by the calling procedure.
+ *
+ */
+static int PtsToRegion(numFullPtBlocks, iCurPtBlock, FirstPtBlock, reg)
+    int  numFullPtBlocks, iCurPtBlock;
+    POINTBLOCK *FirstPtBlock;
+    GdkRegion *reg;
+{
+    GdkRegionBox *rects;
+    GdkPoint *pts;
+    POINTBLOCK *CurPtBlock;
+    int i;
+    GdkRegionBox *extents;
+    int numRects;
+
+    extents = &reg->extents;
+    numRects = ((numFullPtBlocks * NUMPTSTOBUFFER) + iCurPtBlock) >> 1;
+    reg->rects = g_renew (GdkRegionBox, reg->rects, numRects);
+    reg->size = numRects;
+    CurPtBlock = FirstPtBlock;
+    rects = reg->rects - 1;
+    numRects = 0;
+    extents->x1 = G_MAXSHORT,  extents->x2 = G_MINSHORT;
+    for ( ; numFullPtBlocks >= 0; numFullPtBlocks--) {
+       /* the loop uses 2 points per iteration */
+       i = NUMPTSTOBUFFER >> 1;
+       if (!numFullPtBlocks)
+           i = iCurPtBlock >> 1;
+       for (pts = CurPtBlock->pts; i--; pts += 2) {
+           if (pts->x == pts[1].x)
+               continue;
+           if (numRects && pts->x == rects->x1 && pts->y == rects->y2 &&
+               pts[1].x == rects->x2 &&
+               (numRects == 1 || rects[-1].y1 != rects->y1) &&
+               (i && pts[2].y > pts[1].y)) {
+               rects->y2 = pts[1].y + 1;
+               continue;
+           }
+           numRects++;
+           rects++;
+           rects->x1 = pts->x;  rects->y1 = pts->y;
+           rects->x2 = pts[1].x;  rects->y2 = pts[1].y + 1;
+           if (rects->x1 < extents->x1)
+               extents->x1 = rects->x1;
+           if (rects->x2 > extents->x2)
+               extents->x2 = rects->x2;
+        }
+       CurPtBlock = CurPtBlock->next;
+    }
+
+    if (numRects) {
+       extents->y1 = reg->rects->y1;
+       extents->y2 = rects->y2;
+    } else {
+       extents->x1 = 0;
+       extents->y1 = 0;
+       extents->x2 = 0;
+       extents->y2 = 0;
+    }
+    reg->numRects = numRects;
+    return(TRUE);
+}
+
+/*
+ *     polytoregion
+ *
+ *     Scan converts a polygon by returning a run-length
+ *     encoding of the resultant bitmap -- the run-length
+ *     encoding is in the form of an array of rectangles.
+ */
+GdkRegion *
+gdk_region_polygon(GdkPoint *Pts, gint Count, GdkFillRule rule)
+{
+    GdkRegion *region;
+    EdgeTableEntry *pAET;   /* Active Edge Table       */
+    int y;                  /* current scanline        */
+    int iPts = 0;           /* number of pts in buffer */
+    EdgeTableEntry *pWETE;  /* Winding Edge Table Entry*/
+    ScanLineList *pSLL;     /* current scanLineList    */
+    GdkPoint *pts;             /* output buffer           */
+    EdgeTableEntry *pPrevAET;        /* ptr to previous AET     */
+    EdgeTable ET;                    /* header node for ET      */
+    EdgeTableEntry AET;              /* header node for AET     */
+    EdgeTableEntry *pETEs;           /* EdgeTableEntries pool   */
+    ScanLineListBlock SLLBlock;      /* header for scanlinelist */
+    int fixWAET = FALSE;
+    POINTBLOCK FirstPtBlock, *curPtBlock; /* PtBlock buffers    */
+    POINTBLOCK *tmpPtBlock;
+    int numFullPtBlocks = 0;
+    region = gdk_region_new ();
+
+    /* special case a rectangle */
+    pts = Pts;
+    if (((Count == 4) ||
+        ((Count == 5) && (pts[4].x == pts[0].x) && (pts[4].y == pts[0].y))) &&
+       (((pts[0].y == pts[1].y) &&
+         (pts[1].x == pts[2].x) &&
+         (pts[2].y == pts[3].y) &&
+         (pts[3].x == pts[0].x)) ||
+        ((pts[0].x == pts[1].x) &&
+         (pts[1].y == pts[2].y) &&
+         (pts[2].x == pts[3].x) &&
+         (pts[3].y == pts[0].y)))) {
+       region->extents.x1 = MIN(pts[0].x, pts[2].x);
+       region->extents.y1 = MIN(pts[0].y, pts[2].y);
+       region->extents.x2 = MAX(pts[0].x, pts[2].x);
+       region->extents.y2 = MAX(pts[0].y, pts[2].y);
+       if ((region->extents.x1 != region->extents.x2) &&
+           (region->extents.y1 != region->extents.y2)) {
+           region->numRects = 1;
+           *(region->rects) = region->extents;
+       }
+       return(region);
+    }
+
+    pETEs = g_new (EdgeTableEntry, Count);
+
+    pts = FirstPtBlock.pts;
+    CreateETandAET(Count, Pts, &ET, &AET, pETEs, &SLLBlock);
+    pSLL = ET.scanlines.next;
+    curPtBlock = &FirstPtBlock;
+    if (rule == GDK_EVEN_ODD_RULE) {
+        /*
+         *  for each scanline
+         */
+        for (y = ET.ymin; y < ET.ymax; y++) {
+            /*
+             *  Add a new edge to the active edge table when we
+             *  get to the next edge.
+             */
+            if (pSLL != NULL && y == pSLL->scanline) {
+                loadAET(&AET, pSLL->edgelist);
+                pSLL = pSLL->next;
+            }
+            pPrevAET = &AET;
+            pAET = AET.next;
+            /*
+             *  for each active edge
+             */
+            while (pAET) {
+                pts->x = pAET->bres.minor_axis,  pts->y = y;
+                pts++, iPts++;
+                /*
+                 *  send out the buffer
+                 */
+                if (iPts == NUMPTSTOBUFFER) {
+                    tmpPtBlock = (POINTBLOCK *)g_malloc(sizeof(POINTBLOCK));
+                    curPtBlock->next = tmpPtBlock;
+                    curPtBlock = tmpPtBlock;
+                    pts = curPtBlock->pts;
+                    numFullPtBlocks++;
+                    iPts = 0;
+                }
+                EVALUATEEDGEEVENODD(pAET, pPrevAET, y);
+            }
+            (void) InsertionSort(&AET);
+        }
+    }
+    else {
+        /*
+         *  for each scanline
+         */
+        for (y = ET.ymin; y < ET.ymax; y++) {
+            /*
+             *  Add a new edge to the active edge table when we
+             *  get to the next edge.
+             */
+            if (pSLL != NULL && y == pSLL->scanline) {
+                loadAET(&AET, pSLL->edgelist);
+                computeWAET(&AET);
+                pSLL = pSLL->next;
+            }
+            pPrevAET = &AET;
+            pAET = AET.next;
+            pWETE = pAET;
+            /*
+             *  for each active edge
+             */
+            while (pAET) {
+                /*
+                 *  add to the buffer only those edges that
+                 *  are in the Winding active edge table.
+                 */
+                if (pWETE == pAET) {
+                    pts->x = pAET->bres.minor_axis,  pts->y = y;
+                    pts++, iPts++;
+                    /*
+                     *  send out the buffer
+                     */
+                    if (iPts == NUMPTSTOBUFFER) {
+                        tmpPtBlock = (POINTBLOCK *)g_malloc(sizeof(POINTBLOCK));
+                        curPtBlock->next = tmpPtBlock;
+                        curPtBlock = tmpPtBlock;
+                        pts = curPtBlock->pts;
+                        numFullPtBlocks++;    iPts = 0;
+                    }
+                    pWETE = pWETE->nextWETE;
+                }
+                EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET);
+            }
+            /*
+             *  recompute the winding active edge table if
+             *  we just resorted or have exited an edge.
+             */
+            if (InsertionSort(&AET) || fixWAET) {
+                computeWAET(&AET);
+                fixWAET = FALSE;
+            }
+        }
+    }
+    FreeStorage(SLLBlock.next);        
+    (void) PtsToRegion(numFullPtBlocks, iPts, &FirstPtBlock, region);
+    for (curPtBlock = FirstPtBlock.next; --numFullPtBlocks >= 0;) {
+       tmpPtBlock = curPtBlock->next;
+       g_free (curPtBlock);
+       curPtBlock = tmpPtBlock;
+    }
+    g_free (pETEs);
+    return(region);
+}
diff --git a/gdk/nanox/gdkproperty-nanox.c b/gdk/nanox/gdkproperty-nanox.c
new file mode 100644 (file)
index 0000000..2c88c70
--- /dev/null
@@ -0,0 +1,55 @@
+#include "gdk.h"
+#include "gdkprivate-nanox.h"
+
+GdkAtom
+gdk_atom_intern (const gchar *atom_name,
+                gboolean     only_if_exists)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+  return 0;
+}
+
+gchar*
+gdk_atom_name (GdkAtom atom)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+  return NULL;
+}
+
+gboolean
+gdk_property_get (GdkWindow   *window,
+                 GdkAtom      property,
+                 GdkAtom      type,
+                 gulong       offset,
+                 gulong       length,
+                 gint         pdelete,
+                 GdkAtom     *actual_property_type,
+                 gint        *actual_format_type,
+                 gint        *actual_length,
+                 guchar     **data)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+  return 0;
+}
+
+void
+gdk_property_change (GdkWindow    *window,
+                    GdkAtom       property,
+                    GdkAtom       type,
+                    gint          format,
+                    GdkPropMode   mode,
+                    const guchar *data,
+                    gint          nelements)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+  return;
+}
+
+void
+gdk_property_delete (GdkWindow *window,
+                    GdkAtom    property)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+  return;
+}
+
diff --git a/gdk/nanox/gdkregion-generic.c b/gdk/nanox/gdkregion-generic.c
new file mode 100644 (file)
index 0000000..0319f93
--- /dev/null
@@ -0,0 +1,1505 @@
+/* $TOG: Region.c /main/31 1998/02/06 17:50:22 kaleb $ */
+/************************************************************************
+
+Copyright 1987, 1988, 1998  The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+                        All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its 
+documentation for any purpose and without fee is hereby granted, 
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in 
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.  
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+************************************************************************/
+/* $XFree86: xc/lib/X11/Region.c,v 1.5 1999/05/09 10:50:01 dawes Exp $ */
+/*
+ * The functions in this file implement the Region abstraction, similar to one
+ * used in the X11 sample server. A Region is simply an area, as the name
+ * implies, and is implemented as a "y-x-banded" array of rectangles. To
+ * explain: Each Region is made up of a certain number of rectangles sorted
+ * by y coordinate first, and then by x coordinate.
+ *
+ * Furthermore, the rectangles are banded such that every rectangle with a
+ * given upper-left y coordinate (y1) will have the same lower-right y
+ * coordinate (y2) and vice versa. If a rectangle has scanlines in a band, it
+ * will span the entire vertical distance of the band. This means that some
+ * areas that could be merged into a taller rectangle will be represented as
+ * several shorter rectangles to account for shorter rectangles to its left
+ * or right but within its "vertical scope".
+ *
+ * An added constraint on the rectangles is that they must cover as much
+ * horizontal area as possible. E.g. no two rectangles in a band are allowed
+ * to touch.
+ *
+ * Whenever possible, bands will be merged together to cover a greater vertical
+ * distance (and thus reduce the number of rectangles). Two bands can be merged
+ * only if the bottom of one touches the top of the other and they have
+ * rectangles in the same places (of the same width, of course). This maintains
+ * the y-x-banding that's so nice to have...
+ */
+
+#include <gdkregion.h>
+#include "gdkregion-generic.h"
+
+#ifdef DEBUG
+#include <stdio.h>
+#define assert(expr) {if (!(expr)) fprintf(stderr,\
+"Assertion failed file %s, line %d: expr\n", __FILE__, __LINE__); }
+#else
+#define assert(expr)
+#endif
+
+typedef void (*overlapFunc) (GdkRegion    *pReg,
+                            GdkRegionBox *r1,
+                            GdkRegionBox *r1End,
+                            GdkRegionBox *r2,
+                            GdkRegionBox *r2End,
+                            gint          y1,
+                            gint          y2);
+typedef void (*nonOverlapFunc) (GdkRegion    *pReg,
+                               GdkRegionBox *r,
+                               GdkRegionBox *rEnd,
+                               gint          y1,
+                               gint          y2);
+
+static void miRegionCopy (GdkRegion      *dstrgn,
+                         GdkRegion      *rgn);
+static void miRegionOp   (GdkRegion      *newReg,
+                         GdkRegion      *reg1,
+                         GdkRegion      *reg2,
+                         overlapFunc     overlapFn,
+                         nonOverlapFunc  nonOverlap1Fn,
+                         nonOverlapFunc  nonOverlap2Fn);
+
+/*     Create a new empty region       */
+
+GdkRegion *
+gdk_region_new ()
+{
+  GdkRegion *temp;
+
+  temp = g_new (GdkRegion, 1);
+  temp->rects = g_new (GdkRegionBox, 1);
+
+  temp->numRects = 0;
+  temp->extents.x1 = 0;
+  temp->extents.y1 = 0;
+  temp->extents.x2 = 0;
+  temp->extents.y2 = 0;
+  temp->size = 1;
+  
+  return temp;
+}
+
+GdkRegion *
+gdk_region_rectangle (GdkRectangle *rectangle)
+{
+  GdkRegion *temp;
+
+  if (rectangle->width <= 0 || rectangle->height <= 0)
+    return gdk_region_new();
+
+  temp = g_new (GdkRegion, 1);
+  temp->rects = g_new (GdkRegionBox, 1);
+
+  temp->numRects = 1;
+  temp->extents.x1 = temp->rects[0].x1 = rectangle->x;
+  temp->extents.y1 = temp->rects[0].y1 = rectangle->y;
+  temp->extents.x2 = temp->rects[0].x2 = rectangle->x + rectangle->width;
+  temp->extents.y2 = temp->rects[0].y2 = rectangle->y + rectangle->height;
+  temp->size = 1;
+  
+  return temp;
+}
+
+GdkRegion *
+gdk_region_copy (GdkRegion *region)
+{
+  GdkRegion *temp;
+
+  temp = g_new (GdkRegion, 1);
+  temp->rects = g_new (GdkRegionBox, region->numRects);
+
+  temp->numRects = region->numRects;
+  temp->extents = region->extents;
+  temp->size = region->numRects;
+  
+  memcpy (temp->rects, region->rects, region->numRects * sizeof (GdkRegionBox));
+
+  return temp;
+}
+
+void
+gdk_region_get_clipbox (GdkRegion *r, GdkRectangle *rect)
+{
+  rect->x = r->extents.x1;
+  rect->y = r->extents.y1;
+  rect->width = r->extents.x2 - r->extents.x1;
+  rect->height = r->extents.y2 - r->extents.y1;
+}
+
+void
+gdk_region_union_with_rect (GdkRegion    *region,
+                           GdkRectangle *rect)
+{
+  GdkRegion tmp_region;
+
+  if (!rect->width || !rect->height)
+    return;
+    
+  tmp_region.rects = &tmp_region.extents;
+  tmp_region.numRects = 1;
+  tmp_region.extents.x1 = rect->x;
+  tmp_region.extents.y1 = rect->y;
+  tmp_region.extents.x2 = rect->x + rect->width;
+  tmp_region.extents.y2 = rect->y + rect->height;
+  tmp_region.size = 1;
+
+  gdk_region_union (region, &tmp_region);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miSetExtents --
+ *     Reset the extents of a region to what they should be. Called by
+ *     miSubtract and miIntersect b/c they can't figure it out along the
+ *     way or do so easily, as miUnion can.
+ *
+ * Results:
+ *     None.
+ *
+ * Side Effects:
+ *     The region's 'extents' structure is overwritten.
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+miSetExtents (GdkRegion *pReg)
+{
+  GdkRegionBox *pBox, *pBoxEnd, *pExtents;
+
+  if (pReg->numRects == 0)
+    {
+      pReg->extents.x1 = 0;
+      pReg->extents.y1 = 0;
+      pReg->extents.x2 = 0;
+      pReg->extents.y2 = 0;
+      return;
+    }
+
+  pExtents = &pReg->extents;
+  pBox = pReg->rects;
+  pBoxEnd = &pBox[pReg->numRects - 1];
+
+    /*
+     * Since pBox is the first rectangle in the region, it must have the
+     * smallest y1 and since pBoxEnd is the last rectangle in the region,
+     * it must have the largest y2, because of banding. Initialize x1 and
+     * x2 from  pBox and pBoxEnd, resp., as good things to initialize them
+     * to...
+     */
+  pExtents->x1 = pBox->x1;
+  pExtents->y1 = pBox->y1;
+  pExtents->x2 = pBoxEnd->x2;
+  pExtents->y2 = pBoxEnd->y2;
+
+  assert(pExtents->y1 < pExtents->y2);
+  while (pBox <= pBoxEnd)
+    {
+      if (pBox->x1 < pExtents->x1)
+       {
+         pExtents->x1 = pBox->x1;
+       }
+      if (pBox->x2 > pExtents->x2)
+       {
+         pExtents->x2 = pBox->x2;
+       }
+      pBox++;
+    }
+  assert(pExtents->x1 < pExtents->x2);
+}
+
+void
+gdk_region_destroy (GdkRegion *r)
+{
+    g_free (r->rects);
+    g_free (r);
+}
+
+
+/* TranslateRegion(pRegion, x, y)
+   translates in place
+   added by raymond
+*/
+
+void
+gdk_region_offset (GdkRegion *region,
+                  gint       x,
+                  gint       y)
+{
+  int nbox;
+  GdkRegionBox *pbox;
+
+  pbox = region->rects;
+  nbox = region->numRects;
+
+  while(nbox--)
+    {
+      pbox->x1 += x;
+      pbox->x2 += x;
+      pbox->y1 += y;
+      pbox->y2 += y;
+      pbox++;
+    }
+  region->extents.x1 += x;
+  region->extents.x2 += x;
+  region->extents.y1 += y;
+  region->extents.y2 += y;
+}
+
+/* 
+   Utility procedure Compress:
+   Replace r by the region r', where 
+     p in r' iff (Quantifer m <= dx) (p + m in r), and
+     Quantifier is Exists if grow is TRUE, For all if grow is FALSE, and
+     (x,y) + m = (x+m,y) if xdir is TRUE; (x,y+m) if xdir is FALSE.
+
+   Thus, if xdir is TRUE and grow is FALSE, r is replaced by the region
+   of all points p such that p and the next dx points on the same
+   horizontal scan line are all in r.  We do this using by noting
+   that p is the head of a run of length 2^i + k iff p is the head
+   of a run of length 2^i and p+2^i is the head of a run of length
+   k. Thus, the loop invariant: s contains the region corresponding
+   to the runs of length shift.  r contains the region corresponding
+   to the runs of length 1 + dxo & (shift-1), where dxo is the original
+   value of dx.  dx = dxo & ~(shift-1).  As parameters, s and t are
+   scratch regions, so that we don't have to allocate them on every
+   call.
+*/
+
+#define ZOpRegion(a,b) if (grow) gdk_region_union (a, b); \
+                        else gdk_region_intersect (a,b)
+#define ZShiftRegion(a,b) if (xdir) gdk_region_offset (a,b,0); \
+                         else gdk_region_offset (a,0,b)
+
+static void
+Compress(GdkRegion *r,
+        GdkRegion *s,
+        GdkRegion *t,
+        guint      dx,
+        int        xdir,
+        int        grow)
+{
+  guint shift = 1;
+
+  miRegionCopy (s, r);
+  while (dx)
+    {
+      if (dx & shift)
+       {
+         ZShiftRegion(r, -(int)shift);
+         ZOpRegion(r, s);
+         dx -= shift;
+         if (!dx) break;
+        }
+      miRegionCopy (t, s);
+      ZShiftRegion(s, -(int)shift);
+      ZOpRegion(s, t);
+      shift <<= 1;
+    }
+}
+
+#undef ZOpRegion
+#undef ZShiftRegion
+#undef ZCopyRegion
+
+void
+gdk_region_shrink (GdkRegion *r,
+                  int        dx,
+                  int        dy)
+{
+  GdkRegion *s, *t;
+  int grow;
+
+  if (!dx && !dy)
+    return;
+
+  s = gdk_region_new ();
+  t = gdk_region_new ();
+
+  grow = (dx < 0);
+  if (grow)
+    dx = -dx;
+  if (dx)
+     Compress(r, s, t, (unsigned) 2*dx, TRUE, grow);
+     
+  grow = (dy < 0);
+  if (grow)
+    dy = -dy;
+  if (dy)
+     Compress(r, s, t, (unsigned) 2*dy, FALSE, grow);
+  
+  gdk_region_offset (r, dx, dy);
+  gdk_region_destroy (s);
+  gdk_region_destroy (t);
+}
+
+\f
+/*======================================================================
+ *         Region Intersection
+ *====================================================================*/
+/*-
+ *-----------------------------------------------------------------------
+ * miIntersectO --
+ *     Handle an overlapping band for miIntersect.
+ *
+ * Results:
+ *     None.
+ *
+ * Side Effects:
+ *     Rectangles may be added to the region.
+ *
+ *-----------------------------------------------------------------------
+ */
+/* static void*/
+static void
+miIntersectO (GdkRegion    *pReg,
+             GdkRegionBox *r1,
+             GdkRegionBox *r1End,
+             GdkRegionBox *r2,
+             GdkRegionBox *r2End,
+             gint          y1,
+             gint          y2)
+{
+  int          x1;
+  int          x2;
+  GdkRegionBox *pNextRect;
+
+  pNextRect = &pReg->rects[pReg->numRects];
+
+  while ((r1 != r1End) && (r2 != r2End))
+    {
+      x1 = MAX (r1->x1,r2->x1);
+      x2 = MIN (r1->x2,r2->x2);
+
+      /*
+       * If there's any overlap between the two rectangles, add that
+       * overlap to the new region.
+       * There's no need to check for subsumption because the only way
+       * such a need could arise is if some region has two rectangles
+       * right next to each other. Since that should never happen...
+       */
+      if (x1 < x2)
+       {
+         assert (y1<y2);
+
+         MEMCHECK (pReg, pNextRect, pReg->rects);
+         pNextRect->x1 = x1;
+         pNextRect->y1 = y1;
+         pNextRect->x2 = x2;
+         pNextRect->y2 = y2;
+         pReg->numRects += 1;
+         pNextRect++;
+         assert (pReg->numRects <= pReg->size);
+       }
+
+      /*
+       * Need to advance the pointers. Shift the one that extends
+       * to the right the least, since the other still has a chance to
+       * overlap with that region's next rectangle, if you see what I mean.
+       */
+      if (r1->x2 < r2->x2)
+       {
+         r1++;
+       }
+      else if (r2->x2 < r1->x2)
+       {
+         r2++;
+       }
+      else
+       {
+         r1++;
+         r2++;
+       }
+    }
+}
+
+void
+gdk_region_intersect (GdkRegion *region,
+                     GdkRegion *other)
+{
+  /* check for trivial reject */
+  if ((!(region->numRects)) || (!(other->numRects))  ||
+      (!EXTENTCHECK(&region->extents, &other->extents)))
+    region->numRects = 0;
+  else
+    miRegionOp (region, region, other, 
+               miIntersectO, (nonOverlapFunc) NULL, (nonOverlapFunc) NULL);
+    
+  /*
+   * Can't alter region's extents before miRegionOp depends on the
+   * extents of the regions being unchanged. Besides, this way there's
+   * no checking against rectangles that will be nuked due to
+   * coalescing, so we have to examine fewer rectangles.
+   */
+  miSetExtents(region);
+}
+
+static void
+miRegionCopy(GdkRegion *dstrgn, GdkRegion *rgn)
+{
+  if (dstrgn != rgn) /*  don't want to copy to itself */
+    {  
+      if (dstrgn->size < rgn->numRects)
+        {
+         dstrgn->rects = g_renew (GdkRegionBox, dstrgn->rects, rgn->numRects);
+         dstrgn->size = rgn->numRects;
+       }
+      dstrgn->numRects = rgn->numRects;
+      dstrgn->extents.x1 = rgn->extents.x1;
+      dstrgn->extents.y1 = rgn->extents.y1;
+      dstrgn->extents.x2 = rgn->extents.x2;
+      dstrgn->extents.y2 = rgn->extents.y2;
+
+      memcpy (dstrgn->rects, rgn->rects, rgn->numRects * sizeof (GdkRegionBox));
+    }
+}
+
+
+/*======================================================================
+ *         Generic Region Operator
+ *====================================================================*/
+
+/*-
+ *-----------------------------------------------------------------------
+ * miCoalesce --
+ *     Attempt to merge the boxes in the current band with those in the
+ *     previous one. Used only by miRegionOp.
+ *
+ * Results:
+ *     The new index for the previous band.
+ *
+ * Side Effects:
+ *     If coalescing takes place:
+ *         - rectangles in the previous band will have their y2 fields
+ *           altered.
+ *         - pReg->numRects will be decreased.
+ *
+ *-----------------------------------------------------------------------
+ */
+/* static int*/
+static int
+miCoalesce (GdkRegion *pReg,         /* Region to coalesce */
+           gint       prevStart,    /* Index of start of previous band */
+           gint       curStart)     /* Index of start of current band */
+{
+  GdkRegionBox *pPrevBox;      /* Current box in previous band */
+  GdkRegionBox *pCurBox;       /* Current box in current band */
+  GdkRegionBox *pRegEnd;       /* End of region */
+  int          curNumRects;    /* Number of rectangles in current
+                                * band */
+  int          prevNumRects;   /* Number of rectangles in previous
+                                * band */
+  int          bandY1;         /* Y1 coordinate for current band */
+
+  pRegEnd = &pReg->rects[pReg->numRects];
+
+  pPrevBox = &pReg->rects[prevStart];
+  prevNumRects = curStart - prevStart;
+
+    /*
+     * Figure out how many rectangles are in the current band. Have to do
+     * this because multiple bands could have been added in miRegionOp
+     * at the end when one region has been exhausted.
+     */
+  pCurBox = &pReg->rects[curStart];
+  bandY1 = pCurBox->y1;
+  for (curNumRects = 0;
+       (pCurBox != pRegEnd) && (pCurBox->y1 == bandY1);
+       curNumRects++)
+    {
+      pCurBox++;
+    }
+    
+  if (pCurBox != pRegEnd)
+    {
+      /*
+       * If more than one band was added, we have to find the start
+       * of the last band added so the next coalescing job can start
+       * at the right place... (given when multiple bands are added,
+       * this may be pointless -- see above).
+       */
+      pRegEnd--;
+      while (pRegEnd[-1].y1 == pRegEnd->y1)
+       {
+         pRegEnd--;
+       }
+      curStart = pRegEnd - pReg->rects;
+      pRegEnd = pReg->rects + pReg->numRects;
+    }
+       
+  if ((curNumRects == prevNumRects) && (curNumRects != 0)) {
+    pCurBox -= curNumRects;
+    /*
+     * The bands may only be coalesced if the bottom of the previous
+     * matches the top scanline of the current.
+     */
+    if (pPrevBox->y2 == pCurBox->y1)
+      {
+       /*
+        * Make sure the bands have boxes in the same places. This
+        * assumes that boxes have been added in such a way that they
+        * cover the most area possible. I.e. two boxes in a band must
+        * have some horizontal space between them.
+        */
+       do
+         {
+           if ((pPrevBox->x1 != pCurBox->x1) ||
+               (pPrevBox->x2 != pCurBox->x2))
+             {
+               /*
+                * The bands don't line up so they can't be coalesced.
+                */
+               return (curStart);
+             }
+           pPrevBox++;
+           pCurBox++;
+           prevNumRects -= 1;
+         } while (prevNumRects != 0);
+
+       pReg->numRects -= curNumRects;
+       pCurBox -= curNumRects;
+       pPrevBox -= curNumRects;
+
+       /*
+        * The bands may be merged, so set the bottom y of each box
+        * in the previous band to that of the corresponding box in
+        * the current band.
+        */
+       do
+         {
+           pPrevBox->y2 = pCurBox->y2;
+           pPrevBox++;
+           pCurBox++;
+           curNumRects -= 1;
+         }
+       while (curNumRects != 0);
+
+       /*
+        * If only one band was added to the region, we have to backup
+        * curStart to the start of the previous band.
+        *
+        * If more than one band was added to the region, copy the
+        * other bands down. The assumption here is that the other bands
+        * came from the same region as the current one and no further
+        * coalescing can be done on them since it's all been done
+        * already... curStart is already in the right place.
+        */
+       if (pCurBox == pRegEnd)
+         {
+           curStart = prevStart;
+         }
+       else
+         {
+           do
+             {
+               *pPrevBox++ = *pCurBox++;
+             }
+           while (pCurBox != pRegEnd);
+         }
+           
+      }
+  }
+  return curStart;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miRegionOp --
+ *     Apply an operation to two regions. Called by miUnion, miInverse,
+ *     miSubtract, miIntersect...
+ *
+ * Results:
+ *     None.
+ *
+ * Side Effects:
+ *     The new region is overwritten.
+ *
+ * Notes:
+ *     The idea behind this function is to view the two regions as sets.
+ *     Together they cover a rectangle of area that this function divides
+ *     into horizontal bands where points are covered only by one region
+ *     or by both. For the first case, the nonOverlapFunc is called with
+ *     each the band and the band's upper and lower extents. For the
+ *     second, the overlapFunc is called to process the entire band. It
+ *     is responsible for clipping the rectangles in the band, though
+ *     this function provides the boundaries.
+ *     At the end of each band, the new region is coalesced, if possible,
+ *     to reduce the number of rectangles in the region.
+ *
+ *-----------------------------------------------------------------------
+ */
+/* static void*/
+static void
+miRegionOp(GdkRegion *newReg,
+          GdkRegion *reg1,
+          GdkRegion *reg2,
+          overlapFunc    overlapFn,            /* Function to call for over-
+                                                * lapping bands */
+          nonOverlapFunc nonOverlap1Fn,        /* Function to call for non-
+                                                * overlapping bands in region
+                                                * 1 */
+          nonOverlapFunc nonOverlap2Fn)        /* Function to call for non-
+                                                * overlapping bands in region
+                                                * 2 */
+{
+    GdkRegionBox *r1;                  /* Pointer into first region */
+    GdkRegionBox *r2;                  /* Pointer into 2d region */
+    GdkRegionBox *r1End;               /* End of 1st region */
+    GdkRegionBox *r2End;               /* End of 2d region */
+    int          ybot;                 /* Bottom of intersection */
+    int          ytop;                 /* Top of intersection */
+    GdkRegionBox *oldRects;            /* Old rects for newReg */
+    int                  prevBand;             /* Index of start of
+                                        * previous band in newReg */
+    int                  curBand;              /* Index of start of current
+                                        * band in newReg */
+    GdkRegionBox *r1BandEnd;           /* End of current band in r1 */
+    GdkRegionBox *r2BandEnd;           /* End of current band in r2 */
+    int          top;                  /* Top of non-overlapping
+                                        * band */
+    int          bot;                  /* Bottom of non-overlapping
+                                        * band */
+    
+    /*
+     * Initialization:
+     * set r1, r2, r1End and r2End appropriately, preserve the important
+     * parts of the destination region until the end in case it's one of
+     * the two source regions, then mark the "new" region empty, allocating
+     * another array of rectangles for it to use.
+     */
+    r1 = reg1->rects;
+    r2 = reg2->rects;
+    r1End = r1 + reg1->numRects;
+    r2End = r2 + reg2->numRects;
+    
+    oldRects = newReg->rects;
+    
+    EMPTY_REGION(newReg);
+
+    /*
+     * Allocate a reasonable number of rectangles for the new region. The idea
+     * is to allocate enough so the individual functions don't need to
+     * reallocate and copy the array, which is time consuming, yet we don't
+     * have to worry about using too much memory. I hope to be able to
+     * nuke the Xrealloc() at the end of this function eventually.
+     */
+    newReg->size = MAX (reg1->numRects, reg2->numRects) * 2;
+    newReg->rects = g_new (GdkRegionBox, newReg->size);
+    
+    /*
+     * Initialize ybot and ytop.
+     * In the upcoming loop, ybot and ytop serve different functions depending
+     * on whether the band being handled is an overlapping or non-overlapping
+     * band.
+     *         In the case of a non-overlapping band (only one of the regions
+     * has points in the band), ybot is the bottom of the most recent
+     * intersection and thus clips the top of the rectangles in that band.
+     * ytop is the top of the next intersection between the two regions and
+     * serves to clip the bottom of the rectangles in the current band.
+     * For an overlapping band (where the two regions intersect), ytop clips
+     * the top of the rectangles of both regions and ybot clips the bottoms.
+     */
+    if (reg1->extents.y1 < reg2->extents.y1)
+      ybot = reg1->extents.y1;
+    else
+      ybot = reg2->extents.y1;
+    
+    /*
+     * prevBand serves to mark the start of the previous band so rectangles
+     * can be coalesced into larger rectangles. qv. miCoalesce, above.
+     * In the beginning, there is no previous band, so prevBand == curBand
+     * (curBand is set later on, of course, but the first band will always
+     * start at index 0). prevBand and curBand must be indices because of
+     * the possible expansion, and resultant moving, of the new region's
+     * array of rectangles.
+     */
+    prevBand = 0;
+    
+    do
+      {
+       curBand = newReg->numRects;
+
+       /*
+        * This algorithm proceeds one source-band (as opposed to a
+        * destination band, which is determined by where the two regions
+        * intersect) at a time. r1BandEnd and r2BandEnd serve to mark the
+        * rectangle after the last one in the current band for their
+        * respective regions.
+        */
+       r1BandEnd = r1;
+       while ((r1BandEnd != r1End) && (r1BandEnd->y1 == r1->y1))
+         {
+           r1BandEnd++;
+         }
+       
+       r2BandEnd = r2;
+       while ((r2BandEnd != r2End) && (r2BandEnd->y1 == r2->y1))
+         {
+           r2BandEnd++;
+         }
+       
+       /*
+        * First handle the band that doesn't intersect, if any.
+        *
+        * Note that attention is restricted to one band in the
+        * non-intersecting region at once, so if a region has n
+        * bands between the current position and the next place it overlaps
+        * the other, this entire loop will be passed through n times.
+        */
+       if (r1->y1 < r2->y1)
+         {
+           top = MAX (r1->y1,ybot);
+           bot = MIN (r1->y2,r2->y1);
+
+           if ((top != bot) && (nonOverlap1Fn != (void (*)())NULL))
+             {
+               (* nonOverlap1Fn) (newReg, r1, r1BandEnd, top, bot);
+             }
+
+           ytop = r2->y1;
+         }
+       else if (r2->y1 < r1->y1)
+         {
+           top = MAX (r2->y1,ybot);
+           bot = MIN (r2->y2,r1->y1);
+
+           if ((top != bot) && (nonOverlap2Fn != (void (*)())NULL))
+             {
+               (* nonOverlap2Fn) (newReg, r2, r2BandEnd, top, bot);
+             }
+
+           ytop = r1->y1;
+         }
+       else
+         {
+           ytop = r1->y1;
+         }
+
+       /*
+        * If any rectangles got added to the region, try and coalesce them
+        * with rectangles from the previous band. Note we could just do
+        * this test in miCoalesce, but some machines incur a not
+        * inconsiderable cost for function calls, so...
+        */
+       if (newReg->numRects != curBand)
+         {
+           prevBand = miCoalesce (newReg, prevBand, curBand);
+         }
+
+       /*
+        * Now see if we've hit an intersecting band. The two bands only
+        * intersect if ybot > ytop
+        */
+       ybot = MIN (r1->y2, r2->y2);
+       curBand = newReg->numRects;
+       if (ybot > ytop)
+         {
+           (* overlapFn) (newReg, r1, r1BandEnd, r2, r2BandEnd, ytop, ybot);
+
+         }
+       
+       if (newReg->numRects != curBand)
+         {
+           prevBand = miCoalesce (newReg, prevBand, curBand);
+         }
+
+       /*
+        * If we've finished with a band (y2 == ybot) we skip forward
+        * in the region to the next band.
+        */
+       if (r1->y2 == ybot)
+         {
+           r1 = r1BandEnd;
+         }
+       if (r2->y2 == ybot)
+         {
+           r2 = r2BandEnd;
+         }
+      } while ((r1 != r1End) && (r2 != r2End));
+
+    /*
+     * Deal with whichever region still has rectangles left.
+     */
+    curBand = newReg->numRects;
+    if (r1 != r1End)
+      {
+       if (nonOverlap1Fn != (nonOverlapFunc )NULL)
+         {
+           do
+             {
+               r1BandEnd = r1;
+               while ((r1BandEnd < r1End) && (r1BandEnd->y1 == r1->y1))
+                 {
+                   r1BandEnd++;
+                 }
+               (* nonOverlap1Fn) (newReg, r1, r1BandEnd,
+                                    MAX (r1->y1,ybot), r1->y2);
+               r1 = r1BandEnd;
+             } while (r1 != r1End);
+         }
+      }
+    else if ((r2 != r2End) && (nonOverlap2Fn != (nonOverlapFunc) NULL))
+      {
+       do
+         {
+           r2BandEnd = r2;
+           while ((r2BandEnd < r2End) && (r2BandEnd->y1 == r2->y1))
+             {
+               r2BandEnd++;
+             }
+           (* nonOverlap2Fn) (newReg, r2, r2BandEnd,
+                              MAX (r2->y1,ybot), r2->y2);
+           r2 = r2BandEnd;
+         } while (r2 != r2End);
+      }
+
+    if (newReg->numRects != curBand)
+    {
+      (void) miCoalesce (newReg, prevBand, curBand);
+    }
+
+    /*
+     * A bit of cleanup. To keep regions from growing without bound,
+     * we shrink the array of rectangles to match the new number of
+     * rectangles in the region. This never goes to 0, however...
+     *
+     * Only do this stuff if the number of rectangles allocated is more than
+     * twice the number of rectangles in the region (a simple optimization...).
+     */
+    if (newReg->numRects < (newReg->size >> 1))
+      {
+       if (REGION_NOT_EMPTY (newReg))
+         {
+           newReg->size = newReg->numRects;
+           newReg->rects = g_renew (GdkRegionBox, newReg->rects, newReg->size);
+         }
+       else
+         {
+           /*
+            * No point in doing the extra work involved in an Xrealloc if
+            * the region is empty
+            */
+           newReg->size = 1;
+           g_free (newReg->rects);
+           newReg->rects = g_new (GdkRegionBox, 1);
+         }
+      }
+    g_free (oldRects);
+}
+
+\f
+/*======================================================================
+ *         Region Union
+ *====================================================================*/
+
+/*-
+ *-----------------------------------------------------------------------
+ * miUnionNonO --
+ *     Handle a non-overlapping band for the union operation. Just
+ *     Adds the rectangles into the region. Doesn't have to check for
+ *     subsumption or anything.
+ *
+ * Results:
+ *     None.
+ *
+ * Side Effects:
+ *     pReg->numRects is incremented and the final rectangles overwritten
+ *     with the rectangles we're passed.
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+miUnionNonO (GdkRegion    *pReg,
+            GdkRegionBox *r,
+            GdkRegionBox *rEnd,
+            gint          y1,
+            gint          y2)
+{
+  GdkRegionBox *pNextRect;
+
+  pNextRect = &pReg->rects[pReg->numRects];
+
+  assert(y1 < y2);
+
+  while (r != rEnd)
+    {
+      assert(r->x1 < r->x2);
+      MEMCHECK(pReg, pNextRect, pReg->rects);
+      pNextRect->x1 = r->x1;
+      pNextRect->y1 = y1;
+      pNextRect->x2 = r->x2;
+      pNextRect->y2 = y2;
+      pReg->numRects += 1;
+      pNextRect++;
+
+      assert(pReg->numRects<=pReg->size);
+      r++;
+    }
+}
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * miUnionO --
+ *     Handle an overlapping band for the union operation. Picks the
+ *     left-most rectangle each time and merges it into the region.
+ *
+ * Results:
+ *     None.
+ *
+ * Side Effects:
+ *     Rectangles are overwritten in pReg->rects and pReg->numRects will
+ *     be changed.
+ *
+ *-----------------------------------------------------------------------
+ */
+
+/* static void*/
+static void
+miUnionO (GdkRegion *pReg,
+         GdkRegionBox *r1,
+         GdkRegionBox *r1End,
+         GdkRegionBox *r2,
+         GdkRegionBox *r2End,
+         gint          y1,
+         gint          y2)
+{
+  GdkRegionBox *       pNextRect;
+    
+  pNextRect = &pReg->rects[pReg->numRects];
+
+#define MERGERECT(r)                                   \
+    if ((pReg->numRects != 0) &&                       \
+       (pNextRect[-1].y1 == y1) &&                     \
+       (pNextRect[-1].y2 == y2) &&                     \
+       (pNextRect[-1].x2 >= r->x1))                    \
+      {                                                \
+       if (pNextRect[-1].x2 < r->x2)                   \
+         {                                             \
+           pNextRect[-1].x2 = r->x2;                   \
+           assert(pNextRect[-1].x1<pNextRect[-1].x2);  \
+         }                                             \
+      }                                                \
+    else                                               \
+      {                                                \
+       MEMCHECK(pReg, pNextRect, pReg->rects);         \
+       pNextRect->y1 = y1;                             \
+       pNextRect->y2 = y2;                             \
+       pNextRect->x1 = r->x1;                          \
+       pNextRect->x2 = r->x2;                          \
+       pReg->numRects += 1;                            \
+        pNextRect += 1;                                \
+      }                                                \
+    assert(pReg->numRects<=pReg->size);                        \
+    r++;
+    
+    assert (y1<y2);
+    while ((r1 != r1End) && (r2 != r2End))
+    {
+       if (r1->x1 < r2->x1)
+       {
+           MERGERECT(r1);
+       }
+       else
+       {
+           MERGERECT(r2);
+       }
+    }
+    
+    if (r1 != r1End)
+    {
+       do
+       {
+           MERGERECT(r1);
+       } while (r1 != r1End);
+    }
+    else while (r2 != r2End)
+    {
+       MERGERECT(r2);
+    }
+}
+
+void
+gdk_region_union (GdkRegion *region,
+                 GdkRegion *other)
+{
+  /*  checks all the simple cases */
+
+    /*
+     * region and other are the same or other is empty
+     */
+  if ((region == other) || (!(other->numRects)))
+    return;
+
+    /* 
+     * region is empty
+     */
+  if (!(region->numRects))
+    {
+      miRegionCopy (region, other);
+      return;
+    }
+
+  /*
+     * region completely subsumes otehr
+     */
+  if ((region->numRects == 1) && 
+      (region->extents.x1 <= other->extents.x1) &&
+      (region->extents.y1 <= other->extents.y1) &&
+      (region->extents.x2 >= other->extents.x2) &&
+      (region->extents.y2 >= other->extents.y2))
+    return;
+
+  /*
+     * other completely subsumes region
+     */
+  if ((other->numRects == 1) && 
+      (other->extents.x1 <= region->extents.x1) &&
+      (other->extents.y1 <= region->extents.y1) &&
+      (other->extents.x2 >= region->extents.x2) &&
+      (other->extents.y2 >= region->extents.y2))
+    {
+      miRegionCopy(region, other);
+      return;
+    }
+
+  miRegionOp (region, region, other, miUnionO, 
+             miUnionNonO, miUnionNonO);
+
+  region->extents.x1 = MIN (region->extents.x1, other->extents.x1);
+  region->extents.y1 = MIN (region->extents.y1, other->extents.y1);
+  region->extents.x2 = MAX (region->extents.x2, other->extents.x2);
+  region->extents.y2 = MAX (region->extents.y2, other->extents.y2);
+}
+
+\f
+/*======================================================================
+ *               Region Subtraction
+ *====================================================================*/
+
+/*-
+ *-----------------------------------------------------------------------
+ * miSubtractNonO --
+ *     Deal with non-overlapping band for subtraction. Any parts from
+ *     region 2 we discard. Anything from region 1 we add to the region.
+ *
+ * Results:
+ *     None.
+ *
+ * Side Effects:
+ *     pReg may be affected.
+ *
+ *-----------------------------------------------------------------------
+ */
+/* static void*/
+static void
+miSubtractNonO1 (GdkRegion    *pReg,
+                GdkRegionBox *r,
+                GdkRegionBox *rEnd,
+                gint          y1,
+                gint          y2)
+{
+  GdkRegionBox *       pNextRect;
+       
+  pNextRect = &pReg->rects[pReg->numRects];
+       
+  assert(y1<y2);
+
+  while (r != rEnd)
+    {
+      assert (r->x1<r->x2);
+      MEMCHECK (pReg, pNextRect, pReg->rects);
+      pNextRect->x1 = r->x1;
+      pNextRect->y1 = y1;
+      pNextRect->x2 = r->x2;
+      pNextRect->y2 = y2;
+      pReg->numRects += 1;
+      pNextRect++;
+
+      assert (pReg->numRects <= pReg->size);
+
+      r++;
+    }
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miSubtractO --
+ *     Overlapping band subtraction. x1 is the left-most point not yet
+ *     checked.
+ *
+ * Results:
+ *     None.
+ *
+ * Side Effects:
+ *     pReg may have rectangles added to it.
+ *
+ *-----------------------------------------------------------------------
+ */
+/* static void*/
+static void
+miSubtractO (GdkRegion    *pReg,
+            GdkRegionBox *r1,
+            GdkRegionBox *r1End,
+            GdkRegionBox *r2,
+            GdkRegionBox *r2End,
+            gint          y1,
+            gint          y2)
+{
+  GdkRegionBox *       pNextRect;
+  int          x1;
+    
+  x1 = r1->x1;
+    
+  assert(y1<y2);
+  pNextRect = &pReg->rects[pReg->numRects];
+
+  while ((r1 != r1End) && (r2 != r2End))
+    {
+      if (r2->x2 <= x1)
+       {
+         /*
+          * Subtrahend missed the boat: go to next subtrahend.
+          */
+         r2++;
+       }
+      else if (r2->x1 <= x1)
+       {
+         /*
+          * Subtrahend preceeds minuend: nuke left edge of minuend.
+          */
+         x1 = r2->x2;
+         if (x1 >= r1->x2)
+           {
+             /*
+              * Minuend completely covered: advance to next minuend and
+              * reset left fence to edge of new minuend.
+              */
+             r1++;
+             if (r1 != r1End)
+               x1 = r1->x1;
+           }
+         else
+           {
+             /*
+              * Subtrahend now used up since it doesn't extend beyond
+              * minuend
+              */
+             r2++;
+           }
+       }
+      else if (r2->x1 < r1->x2)
+       {
+         /*
+          * Left part of subtrahend covers part of minuend: add uncovered
+          * part of minuend to region and skip to next subtrahend.
+          */
+         assert(x1<r2->x1);
+         MEMCHECK(pReg, pNextRect, pReg->rects);
+         pNextRect->x1 = x1;
+         pNextRect->y1 = y1;
+         pNextRect->x2 = r2->x1;
+         pNextRect->y2 = y2;
+         pReg->numRects += 1;
+         pNextRect++;
+
+         assert(pReg->numRects<=pReg->size);
+
+         x1 = r2->x2;
+         if (x1 >= r1->x2)
+           {
+             /*
+              * Minuend used up: advance to new...
+              */
+             r1++;
+             if (r1 != r1End)
+               x1 = r1->x1;
+           }
+         else
+           {
+             /*
+              * Subtrahend used up
+              */
+             r2++;
+           }
+       }
+      else
+       {
+         /*
+          * Minuend used up: add any remaining piece before advancing.
+          */
+         if (r1->x2 > x1)
+           {
+             MEMCHECK(pReg, pNextRect, pReg->rects);
+             pNextRect->x1 = x1;
+             pNextRect->y1 = y1;
+             pNextRect->x2 = r1->x2;
+             pNextRect->y2 = y2;
+             pReg->numRects += 1;
+             pNextRect++;
+             assert(pReg->numRects<=pReg->size);
+           }
+         r1++;
+         x1 = r1->x1;
+       }
+    }
+
+  /*
+     * Add remaining minuend rectangles to region.
+     */
+  while (r1 != r1End)
+    {
+      assert(x1<r1->x2);
+      MEMCHECK(pReg, pNextRect, pReg->rects);
+      pNextRect->x1 = x1;
+      pNextRect->y1 = y1;
+      pNextRect->x2 = r1->x2;
+      pNextRect->y2 = y2;
+      pReg->numRects += 1;
+      pNextRect++;
+
+      assert(pReg->numRects<=pReg->size);
+
+      r1++;
+      if (r1 != r1End)
+       {
+         x1 = r1->x1;
+       }
+    }
+}
+       
+/*-
+ *-----------------------------------------------------------------------
+ * gdk_region_subtract --
+ *     Subtract other from region and leave the result in region.
+ *
+ * Results:
+ *     TRUE.
+ *
+ * Side Effects:
+ *     region is overwritten.
+ *
+ *-----------------------------------------------------------------------
+ */
+
+void
+gdk_region_subtract (GdkRegion *region,
+                    GdkRegion *other)
+{
+  /* check for trivial reject */
+  if ((!(region->numRects)) || (!(other->numRects)) ||
+      (!EXTENTCHECK(&region->extents, &other->extents)))
+    return;
+  miRegionOp (region, region, other, miSubtractO,
+             miSubtractNonO1, (nonOverlapFunc) NULL);
+
+  /*
+   * Can't alter region's extents before we call miRegionOp because miRegionOp
+   * depends on the extents of those regions being the unaltered. Besides, this
+   * way there's no checking against rectangles that will be nuked
+   * due to coalescing, so we have to examine fewer rectangles.
+   */
+  miSetExtents (region);
+}
+
+void
+gdk_region_xor (GdkRegion *sra,
+               GdkRegion *srb)
+{
+  GdkRegion *trb;
+
+  trb = gdk_region_copy (srb);
+
+  gdk_region_subtract (trb, sra);
+  gdk_region_subtract (sra, srb);
+
+  gdk_region_union (sra,trb);
+  
+  gdk_region_destroy (trb);
+}
+
+/*
+ * Check to see if the region is empty.  Assumes a region is passed 
+ * as a parameter
+ */
+gboolean
+gdk_region_empty (GdkRegion *r)
+{
+  if (r->numRects == 0)
+    return TRUE;
+  else
+    return FALSE;
+}
+
+/*
+ *     Check to see if two regions are equal   
+ */
+gboolean
+gdk_region_equal (GdkRegion *r1,
+                 GdkRegion *r2)
+{
+  int i;
+
+  if (r1->numRects != r2->numRects) return FALSE;
+  else if (r1->numRects == 0) return TRUE;
+  else if (r1->extents.x1 != r2->extents.x1) return FALSE;
+  else if (r1->extents.x2 != r2->extents.x2) return FALSE;
+  else if (r1->extents.y1 != r2->extents.y1) return FALSE;
+  else if (r1->extents.y2 != r2->extents.y2) return FALSE;
+  else
+    for(i=0; i < r1->numRects; i++ )
+      {
+       if (r1->rects[i].x1 != r2->rects[i].x1) return FALSE;
+       else if (r1->rects[i].x2 != r2->rects[i].x2) return FALSE;
+       else if (r1->rects[i].y1 != r2->rects[i].y1) return FALSE;
+       else if (r1->rects[i].y2 != r2->rects[i].y2) return FALSE;
+      }
+  return TRUE;
+}
+
+gboolean
+gdk_region_point_in (GdkRegion *region,
+                    int        x,
+                    int        y)
+{
+  int i;
+
+  if (region->numRects == 0)
+    return FALSE;
+  if (!INBOX(region->extents, x, y))
+    return FALSE;
+  for (i=0; i<region->numRects; i++)
+    {
+      if (INBOX (region->rects[i], x, y))
+       return TRUE;
+    }
+  return FALSE;
+}
+
+GdkOverlapType
+gdk_region_rect_in (GdkRegion    *region,
+                   GdkRectangle *rectangle)
+{
+  GdkRegionBox *pbox;
+  GdkRegionBox *pboxEnd;
+  GdkRegionBox  rect;
+  GdkRegionBox *prect = &rect;
+  gboolean      partIn, partOut;
+
+  gint rx = rectangle->x;
+  gint ry = rectangle->y;
+  
+  prect->x1 = rx;
+  prect->y1 = ry;
+  prect->x2 = rx + rectangle->width;
+  prect->y2 = ry + rectangle->height;
+    
+    /* this is (just) a useful optimization */
+  if ((region->numRects == 0) || !EXTENTCHECK (&region->extents, prect))
+    return GDK_OVERLAP_RECTANGLE_IN;
+
+  partOut = FALSE;
+  partIn = FALSE;
+
+    /* can stop when both partOut and partIn are TRUE, or we reach prect->y2 */
+  for (pbox = region->rects, pboxEnd = pbox + region->numRects;
+       pbox < pboxEnd;
+       pbox++)
+    {
+
+      if (pbox->y2 <= ry)
+       continue;       /* getting up to speed or skipping remainder of band */
+
+      if (pbox->y1 > ry)
+       {
+         partOut = TRUE;       /* missed part of rectangle above */
+         if (partIn || (pbox->y1 >= prect->y2))
+           break;
+         ry = pbox->y1;        /* x guaranteed to be == prect->x1 */
+       }
+
+      if (pbox->x2 <= rx)
+       continue;               /* not far enough over yet */
+
+      if (pbox->x1 > rx)
+       {
+         partOut = TRUE;       /* missed part of rectangle to left */
+         if (partIn)
+           break;
+       }
+
+      if (pbox->x1 < prect->x2)
+       {
+         partIn = TRUE;        /* definitely overlap */
+         if (partOut)
+           break;
+       }
+
+      if (pbox->x2 >= prect->x2)
+       {
+         ry = pbox->y2;        /* finished with this band */
+         if (ry >= prect->y2)
+           break;
+         rx = prect->x1;       /* reset x out to left again */
+       }
+      else
+       {
+         /*
+          * Because boxes in a band are maximal width, if the first box
+          * to overlap the rectangle doesn't completely cover it in that
+          * band, the rectangle must be partially out, since some of it
+          * will be uncovered in that band. partIn will have been set true
+          * by now...
+          */
+         break;
+       }
+
+    }
+
+  return (partIn ?
+            ((ry < prect->y2) ?
+             GDK_OVERLAP_RECTANGLE_PART : GDK_OVERLAP_RECTANGLE_IN) : 
+         GDK_OVERLAP_RECTANGLE_OUT);
+}
diff --git a/gdk/nanox/gdkregion-nanox.c b/gdk/nanox/gdkregion-nanox.c
new file mode 100644 (file)
index 0000000..b0bcc33
--- /dev/null
@@ -0,0 +1,107 @@
+#include "gdkprivate-nanox.h"
+
+GdkRegion*
+gdk_region_new (void)
+{
+  return NULL;
+}
+
+
+void
+gdk_region_destroy (GdkRegion *region)
+{
+}
+
+
+gboolean
+gdk_region_empty (GdkRegion      *region)
+{
+  return 1;
+}
+
+gboolean
+gdk_region_equal (GdkRegion      *region1,
+                  GdkRegion      *region2)
+{
+  return 1;
+}
+
+
+void
+gdk_region_get_clipbox(GdkRegion    *region,
+                      GdkRectangle *rectangle)
+{
+}
+
+gboolean
+gdk_region_point_in (GdkRegion      *region,
+                     gint           x,
+                    gint           y)
+{
+  return 0;
+}
+
+GdkOverlapType
+gdk_region_rect_in (GdkRegion      *region,
+                    GdkRectangle   *rect)
+{
+  return 0;
+}
+
+GdkRegion *
+gdk_region_polygon (GdkPoint    *points,
+                   gint         npoints,
+                   GdkFillRule  fill_rule)
+{
+  return NULL;
+}
+
+void          
+gdk_region_offset (GdkRegion      *region,
+                   gint           dx,
+                  gint           dy)
+{
+}
+
+void
+gdk_region_shrink (GdkRegion      *region,
+                   gint           dx,
+                  gint           dy)
+{
+}
+
+GdkRegion*    
+gdk_region_union_with_rect (GdkRegion      *region,
+                            GdkRectangle   *rect)
+{
+  return NULL;
+}
+
+GdkRegion*    
+gdk_regions_intersect (GdkRegion      *source1,
+                       GdkRegion      *source2)
+{
+  return NULL;
+}
+
+GdkRegion* 
+gdk_regions_union (GdkRegion      *source1,
+                   GdkRegion      *source2)
+{
+  return NULL;
+}
+
+GdkRegion*    
+gdk_regions_subtract (GdkRegion      *source1,
+                      GdkRegion      *source2)
+{
+  return NULL;
+}
+
+GdkRegion*    
+gdk_regions_xor (GdkRegion      *source1,
+                 GdkRegion      *source2)
+{
+  return NULL;
+}
+
diff --git a/gdk/nanox/gdkselection-nanox.c b/gdk/nanox/gdkselection-nanox.c
new file mode 100644 (file)
index 0000000..60d7fca
--- /dev/null
@@ -0,0 +1,89 @@
+#include "gdk.h"
+#include "gdkprivate-nanox.h"
+
+gboolean
+gdk_selection_owner_set (GdkWindow *owner,
+                        GdkAtom    selection,
+                        guint32    time,
+                        gboolean   send_event)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+  return 0;
+}
+
+
+GdkWindow*
+gdk_selection_owner_get (GdkAtom selection)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+  return NULL;
+}
+
+
+void
+gdk_selection_convert (GdkWindow *requestor,
+                      GdkAtom    selection,
+                      GdkAtom    target,
+                      guint32    time)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+}
+
+
+gint
+gdk_selection_property_get (GdkWindow  *requestor,
+                           guchar    **data,
+                           GdkAtom    *ret_type,
+                           gint       *ret_format)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+  return 0;
+}
+
+
+void
+gdk_selection_send_notify (guint32  requestor,
+                          GdkAtom  selection,
+                          GdkAtom  target,
+                          GdkAtom  property,
+                          guint32  time)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+}
+
+gint
+gdk_text_property_to_text_list (GdkAtom       encoding,
+                               gint          format, 
+                               const guchar *text,
+                               gint          length,
+                               gchar      ***list)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+  return 0;
+}
+
+
+void
+gdk_free_text_list (gchar **list)
+{
+  g_return_if_fail (list != NULL);
+
+}
+
+gint
+gdk_string_to_compound_text (const gchar *str,
+                            GdkAtom     *encoding,
+                            gint        *format,
+                            guchar     **ctext,
+                            gint        *length)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+  return 0;
+}
+
+void gdk_free_compound_text (guchar *ctext)
+{
+/*  if (ctext)
+    g_free (ctext);*/
+}
+
diff --git a/gdk/nanox/gdkvisual-nanox.c b/gdk/nanox/gdkvisual-nanox.c
new file mode 100644 (file)
index 0000000..616410d
--- /dev/null
@@ -0,0 +1,95 @@
+
+#include "gdkvisual.h"
+#include "gdkprivate-nanox.h"
+#include <glib.h>
+
+static GdkVisual system_visual;
+
+void
+gdk_visual_init (void)
+{
+  system_visual.type = GDK_VISUAL_TRUE_COLOR;
+  system_visual.depth = 24;
+  system_visual.bits_per_rgb = 8;
+}
+
+GdkVisual*
+gdk_visual_ref (GdkVisual *visual)
+{
+  return visual;
+}
+
+void
+gdk_visual_unref (GdkVisual *visual)
+{
+  return;
+}
+
+gint
+gdk_visual_get_best_depth (void)
+{
+  return 24;
+}
+
+GdkVisualType
+gdk_visual_get_best_type (void)
+{
+  return GDK_VISUAL_TRUE_COLOR;
+}
+
+GdkVisual*
+gdk_visual_get_system (void)
+{
+  return ((GdkVisual*) &system_visual);
+}
+
+GdkVisual*
+gdk_visual_get_best (void)
+{
+  return ((GdkVisual*) &system_visual);
+}
+
+GdkVisual*
+gdk_visual_get_best_with_type (GdkVisualType visual_type)
+{
+  if (visual_type == GDK_VISUAL_TRUE_COLOR)
+    return &system_visual;
+  return NULL;
+}
+
+GdkVisual*
+gdk_visual_get_best_with_both (gint          depth,
+                              GdkVisualType visual_type)
+{
+  if (visual_type == GDK_VISUAL_TRUE_COLOR && depth == 24)
+    return &system_visual;
+  return NULL;
+}
+
+void
+gdk_query_depths  (gint **depths,
+                  gint  *count)
+{
+  if (count)
+    *count = 1;
+  if (depths)
+    *depths[0] = 24;
+}
+
+void
+gdk_query_visual_types (GdkVisualType **visual_types,
+                       gint           *count)
+{
+  if (count)
+    *count = 1;
+  if (visual_types)
+    *visual_types[0] = GDK_VISUAL_TRUE_COLOR;
+}
+
+GList*
+gdk_list_visuals (void)
+{
+  return g_list_append(NULL, &system_visual);
+}
+
+
diff --git a/gdk/nanox/gdkwindow-nanox.c b/gdk/nanox/gdkwindow-nanox.c
new file mode 100644 (file)
index 0000000..c537c8f
--- /dev/null
@@ -0,0 +1,600 @@
+
+#include "gdk.h"
+#include "config.h"
+
+#include "gdkwindow.h"
+#include "gdkprivate-nanox.h"
+#include "gdkprivate.h"
+
+static void create_toplevel (GR_WINDOW_ID parent, GR_WINDOW_ID win, int x, int y, int width, int height);
+static int  manage_event (GR_EVENT *event);
+static void set_title (GR_WINDOW_ID win, char* title);
+
+typedef struct {
+               char * name;
+               void (*create_toplevel) (GR_WINDOW_ID parent, GR_WINDOW_ID win, int x, int y, int width, int height);
+               int  (*manage_event) (GR_EVENT *event);
+               void (*set_title) (GR_WINDOW_ID win, char* title);
+} GdkWindowManager;
+
+typedef struct {
+               GR_WINDOW_ID pwin;
+               GR_WINDOW_ID win;
+               char *title;
+               GdkWMFunction functions;
+               GdkWMDecoration decors;
+} WMInfo;
+
+static GdkWindowManager test_wm = {
+               "test",
+               create_toplevel,
+               manage_event,
+               set_title
+};
+
+static GdkWindowManager *default_wm = &test_wm;
+static GHashTable * wm_hash = NULL;
+GdkDrawableClass _gdk_windowing_window_class;
+
+static void create_toplevel (GR_WINDOW_ID parent, GR_WINDOW_ID win, int x, int y, int width, int height)
+{
+               WMInfo *winfo;
+
+               winfo = g_new0(WMInfo, 1);
+       winfo->pwin = GrNewWindow(parent, x, y-20, width, height+20, 0, RGB(150, 50,150), WHITE);
+               winfo->win = win;
+               GrReparentWindow(winfo->pwin, win, 20, 0);
+               if (!wm_hash)
+                               wm_hash = g_hash_table_new(g_int_hash, g_int_equal);
+               g_hash_table_insert(wm_hash, winfo->pwin, winfo);
+}
+
+static int  manage_event (GR_EVENT *event) {
+               return 0;
+}
+
+static void set_title (GR_WINDOW_ID win, char* title) {
+}
+
+
+static void
+gdk_nanox_window_destroy (GdkDrawable *drawable)
+{
+  if (!GDK_DRAWABLE_DESTROYED (drawable))
+    {
+      if (GDK_DRAWABLE_TYPE (drawable) == GDK_WINDOW_FOREIGN)
+       gdk_xid_table_remove (GDK_DRAWABLE_XID (drawable));
+      else
+       g_warning ("losing last reference to undestroyed window\n");
+    }
+
+  g_free (GDK_DRAWABLE_XDATA (drawable));
+}
+
+static GdkWindowPrivate*
+gdk_window_nanox_alloc() {
+  GdkWindow *window;
+  GdkWindowPrivate *private;
+  
+  static GdkDrawableClass klass;
+  static gboolean initialized = FALSE;
+
+  if (!initialized)
+    {
+      initialized = TRUE;
+      
+      klass = _gdk_nanox_drawable_class;
+      klass.destroy = gdk_nanox_window_destroy;
+    }
+
+  window = _gdk_window_alloc ();
+  private = (GdkWindowPrivate *)window;
+
+  private->drawable.klass = &klass;
+  private->drawable.klass_data = g_new (GdkDrawableXData, 1);
+
+  return window;
+}
+
+static void
+gdk_window_internal_destroy (GdkWindow *window,
+                            gboolean   xdestroy,
+                            gboolean   our_destroy)
+{
+}
+
+GR_WINDOW_ID gdk_root_window = GR_ROOT_WINDOW_ID;
+
+void
+gdk_window_init (void)
+{
+  GdkWindowPrivate *private;
+
+  gdk_parent_root = gdk_window_nanox_alloc ();
+  private = (GdkWindowPrivate *)gdk_parent_root;
+  
+  GDK_DRAWABLE_XDATA (gdk_parent_root)->xid = gdk_root_window;
+
+  private->drawable.window_type = GDK_WINDOW_ROOT;
+  private->drawable.width = gdk_screen_width();
+  private->drawable.height = gdk_screen_height();
+  
+  gdk_window_set_events(private, -1);
+  gdk_xid_table_insert (&gdk_root_window, gdk_parent_root);
+}
+
+
+GdkWindow*
+gdk_window_new (GdkWindow     *parent,
+               GdkWindowAttr *attributes,
+               gint           attributes_mask)
+{
+  GR_WINDOW_ID new_win;
+  GdkWindowPrivate *private, *parent_private;
+  int x, y, width, height;
+  int border = 1;
+  
+  if (!parent)
+    parent = gdk_parent_root;
+
+  if (GDK_DRAWABLE_DESTROYED (parent))
+    return NULL;
+  private->parent = parent;
+
+  parent_private = (GdkWindowPrivate*)parent;
+
+  if (attributes_mask & GDK_WA_X)
+    x = attributes->x;
+  else
+    x = 0;
+  
+  if (attributes_mask & GDK_WA_Y)
+    y = attributes->y;
+  else
+    y = 0;
+  
+  width = attributes->width;
+  height = attributes->height;
+  
+  private = gdk_window_nanox_alloc();
+  private->x = x;
+  private->y = y;
+  private->drawable.width = (attributes->width > 1) ? (attributes->width) : (1);
+  private->drawable.height = (attributes->height > 1) ? (attributes->height) : (1);
+  private->drawable.window_type = attributes->window_type;
+
+  if (attributes->window_type == GDK_WINDOW_TOPLEVEL || attributes->window_type == GDK_WINDOW_DIALOG)
+                 border = 2;
+  /* if toplevel reparent to our own window managed window... (check override_redirect) */
+  if (attributes->wclass == GDK_INPUT_OUTPUT)
+    new_win = GrNewWindow(GDK_WINDOW_XWINDOW(parent), x, y, width, height, border, RGB(150,150,150), WHITE);
+  else
+    new_win = GrNewInputWindow(GDK_WINDOW_XWINDOW(parent), x, y, width, height);
+
+  GDK_DRAWABLE_XDATA(private)->xid = new_win;
+  gdk_drawable_ref(private);
+  
+  private->drawable.colormap = gdk_colormap_get_system (); 
+
+  gdk_xid_table_insert (&GDK_DRAWABLE_XID(private), private);
+  g_message("created window %d %d %d %d %d", new_win, x, y, width, height);
+  GrSelectEvents(GDK_DRAWABLE_XID(private), -1);
+  return (GdkWindow*)private;;
+}
+
+
+GdkWindow *
+gdk_window_foreign_new (guint32 anid)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+       return NULL;
+}
+
+void
+gdk_window_destroy (GdkWindow *window)
+{
+  gdk_window_internal_destroy (window, TRUE, TRUE);
+  gdk_drawable_unref (window);
+}
+
+void
+gdk_window_destroy_notify (GdkWindow *window)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+}
+
+void
+gdk_window_show (GdkWindow *window)
+{
+  GdkWindowPrivate *private;
+  
+  g_return_if_fail (window != NULL);
+  
+  private = (GdkWindowPrivate*) window;
+  if (!private->drawable.destroyed)
+    {
+      private->mapped = TRUE;
+      GrRaiseWindow (GDK_DRAWABLE_XID (window));
+      GrMapWindow (GDK_DRAWABLE_XID (window));
+    }
+}
+
+void
+gdk_window_hide (GdkWindow *window)
+{
+  GdkWindowPrivate *private;
+  
+  g_return_if_fail (window != NULL);
+  
+  private = (GdkWindowPrivate*) window;
+  if (!private->drawable.destroyed)
+    {
+      private->mapped = FALSE;
+      GrUnmapWindow (GDK_DRAWABLE_XID (window));
+    }
+}
+
+void
+gdk_window_raise (GdkWindow *window)
+{
+  g_return_if_fail (window != NULL);
+  g_return_if_fail (GDK_IS_WINDOW (window));
+  
+  if (!GDK_DRAWABLE_DESTROYED (window))
+    GrRaiseWindow (GDK_DRAWABLE_XID (window));
+}
+
+void
+gdk_window_lower (GdkWindow *window)
+{
+  g_return_if_fail (window != NULL);
+  g_return_if_fail (GDK_IS_WINDOW (window));
+  
+  if (!GDK_DRAWABLE_DESTROYED (window))
+    GrLowerWindow (GDK_DRAWABLE_XID (window));
+}
+
+void
+gdk_window_withdraw (GdkWindow *window)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+}
+
+void
+gdk_window_move (GdkWindow *window,
+                gint       x,
+                gint       y)
+{
+  GrMoveWindow(GDK_DRAWABLE_XID(window), x, y);
+}
+
+void
+gdk_window_resize (GdkWindow *window,
+                  gint       width,
+                  gint       height)
+{
+  GrResizeWindow(GDK_DRAWABLE_XID(window), width, height);
+}
+
+void
+gdk_window_move_resize (GdkWindow *window,
+                       gint       x,
+                       gint       y,
+                       gint       width,
+                       gint       height)
+{
+  GrMoveWindow(GDK_DRAWABLE_XID(window), x, y);
+  GrResizeWindow(GDK_DRAWABLE_XID(window), width, height);
+}
+
+void
+gdk_window_reparent (GdkWindow *window,
+                    GdkWindow *new_parent,
+                    gint       x,
+                    gint       y)
+{
+  GrReparentWindow(GDK_DRAWABLE_XID(window), GDK_DRAWABLE_XID(new_parent), x, y);
+}
+
+void
+gdk_window_clear (GdkWindow *window)
+{
+  g_return_if_fail (window != NULL);
+  g_return_if_fail (GDK_IS_WINDOW (window));
+  
+  if (!GDK_DRAWABLE_DESTROYED (window))
+    GrClearWindow (GDK_DRAWABLE_XID (window), 0);
+}
+
+void
+_gdk_windowing_window_clear_area (GdkWindow *window,
+                      gint       x,
+                      gint       y,
+                      gint       width,
+                      gint       height)
+{
+  g_return_if_fail (window != NULL);
+  g_return_if_fail (GDK_IS_WINDOW (window));
+  
+  if (!GDK_DRAWABLE_DESTROYED (window))
+    GrClearWindow (GDK_DRAWABLE_XID (window), 0);
+}
+
+void
+_gdk_windowing_window_clear_area_e (GdkWindow *window,
+                        gint       x,
+                        gint       y,
+                        gint       width,
+                        gint       height)
+{
+  g_return_if_fail (window != NULL);
+  g_return_if_fail (GDK_IS_WINDOW (window));
+  
+  if (!GDK_DRAWABLE_DESTROYED (window))
+    GrClearWindow (GDK_DRAWABLE_XID (window), 1);
+}
+
+void
+gdk_window_set_hints (GdkWindow *window,
+                     gint       x,
+                     gint       y,
+                     gint       min_width,
+                     gint       min_height,
+                     gint       max_width,
+                     gint       max_height,
+                     gint       flags)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+}
+
+
+void 
+gdk_window_set_geometry_hints (GdkWindow      *window,
+                              GdkGeometry    *geometry,
+                              GdkWindowHints  geom_mask)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+}
+
+
+void
+gdk_window_set_title (GdkWindow   *window,
+                     const gchar *title)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+}
+
+void          
+gdk_window_set_role (GdkWindow   *window,
+                    const gchar *role)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+}
+
+
+void          
+gdk_window_set_transient_for (GdkWindow *window, 
+                             GdkWindow *parent)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+}
+
+void
+gdk_window_set_background (GdkWindow *window,
+                          GdkColor  *color)
+{
+  g_return_if_fail (window != NULL);
+  g_return_if_fail (GDK_IS_WINDOW (window));
+  
+               g_message("unimplemented %s", __FUNCTION__);
+  if (GDK_DRAWABLE_DESTROYED (window))
+    return;
+}
+
+
+void
+gdk_window_set_back_pixmap (GdkWindow *window,
+                           GdkPixmap *pixmap,
+                           gboolean   parent_relative)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+}
+
+void
+gdk_window_set_cursor (GdkWindow *window,
+                      GdkCursor *cursor)
+{
+}
+
+void
+gdk_window_get_geometry (GdkWindow *window,
+                        gint      *x,
+                        gint      *y,
+                        gint      *width,
+                        gint      *height,
+                        gint      *depth)
+{
+  GR_WINDOW_INFO winfo;
+  g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
+  
+  if (!window)
+    window = gdk_parent_root;
+  
+  if (!GDK_DRAWABLE_DESTROYED (window))
+    {
+      GrGetWindowInfo(GDK_DRAWABLE_XID(window), &winfo);
+       if (x)
+         *x = winfo.x;
+       if (y)
+         *y = winfo.y;
+       if (width)
+         *width = winfo.width;
+       if (height)
+         *height = winfo.height;
+       if (depth)
+         *depth = 24;
+    }
+}
+
+
+gint
+gdk_window_get_origin (GdkWindow *window,
+                      gint      *x,
+                      gint      *y)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+       return 0;
+}
+
+gboolean
+gdk_window_get_deskrelative_origin (GdkWindow *window,
+                                   gint      *x,
+                                   gint      *y)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+       return 0;
+}
+
+
+void
+gdk_window_get_root_origin (GdkWindow *window,
+                           gint      *x,
+                           gint      *y)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+}
+
+
+GdkWindow*
+gdk_window_get_pointer (GdkWindow       *window,
+                       gint            *x,
+                       gint            *y,
+                       GdkModifierType *mask)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+       return NULL;
+}
+
+GdkWindow*
+gdk_window_at_pointer (gint *win_x,
+                      gint *win_y)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+       return NULL;
+}
+
+
+GList*
+gdk_window_get_children (GdkWindow *window)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+       return NULL;
+}
+
+GdkEventMask  
+gdk_window_get_events (GdkWindow *window)
+{
+       return -1;
+}
+
+
+void          
+gdk_window_set_events (GdkWindow       *window,
+                      GdkEventMask     event_mask)
+{
+  GrSelectEvents(GDK_DRAWABLE_XID(window), -1);
+}
+
+
+void
+gdk_window_shape_combine_mask (GdkWindow *window,
+                              GdkBitmap *mask,
+                              gint x, gint y)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+}
+
+void
+gdk_window_set_override_redirect (GdkWindow *window,
+                                 gboolean override_redirect)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+}
+
+
+void          
+gdk_window_set_icon (GdkWindow *window, 
+                    GdkWindow *icon_window,
+                    GdkPixmap *pixmap,
+                    GdkBitmap *mask)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+}
+
+
+void          
+gdk_window_set_icon_name (GdkWindow   *window, 
+                         const gchar *name)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+}
+
+
+void          
+gdk_window_set_group (GdkWindow *window, 
+                     GdkWindow *leader)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+}
+
+void
+gdk_window_set_decorations (GdkWindow      *window,
+                           GdkWMDecoration decorations)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+}
+
+
+void
+gdk_window_set_functions (GdkWindow    *window,
+                         GdkWMFunction functions)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+}
+
+void
+gdk_window_set_child_shapes (GdkWindow *window)
+{
+  g_return_if_fail (window != NULL);
+  g_return_if_fail (GDK_IS_WINDOW (window));
+               g_message("unimplemented %s", __FUNCTION__);
+}
+
+
+void
+gdk_window_merge_child_shapes (GdkWindow *window)
+{
+  g_return_if_fail (window != NULL);
+  g_return_if_fail (GDK_IS_WINDOW (window));
+               g_message("unimplemented %s", __FUNCTION__);
+}
+
+
+gboolean 
+gdk_window_set_static_gravities (GdkWindow *window,
+                                gboolean   use_static)
+{
+               g_message("unimplemented %s", __FUNCTION__);
+       return 0;
+}
+
+void
+_gdk_windowing_window_get_offsets (GdkWindow *window, gint      *x_offset, gint      *y_offset) {
+               *x_offset = *y_offset = 0;
+}
+
+gboolean
+_gdk_windowing_window_queue_antiexpose (GdkWindow *window, GdkRegion *area) {
+       return FALSE;
+}
index 43b19e47fa7074b817fa39127010b7bb6bf79507..781a3aad903fc05aa14cda10802b4b8211dd4bd4 100644 (file)
@@ -30,6 +30,8 @@
 #include "x11/gdkx.h"
 #elif defined (GDK_WINDOWING_WIN32)
 #include "win32/gdkwin32.h"
+#elif defined (GDK_WINDOWING_NANOX)
+#include "nanox/gdkprivate-nanox.h"
 #endif
 
 #include "gdk/gdkkeysyms.h"
index ea68dd97aa86f9bd3f5d19cd1e7f8a080af6246c..116e8e35fae9cdff3f3c67a04658af0b587637fe 100644 (file)
@@ -31,6 +31,8 @@
 #include "x11/gdkx.h"
 #elif defined (GDK_WINDOWING_WIN32)
 #include "win32/gdkwin32.h"
+#elif defined (GDK_WINDOWING_NANOX)
+#include "nanox/gdkprivate-nanox.h"
 #endif
 
 #include "gdk/gdkkeysyms.h"
index 6f6ce8d04ba867fd8126df0b7b24fa5cb4728470..2bfbf95ed0044b67b84ebe034df8e5598b17e3a4 100644 (file)
@@ -59,6 +59,8 @@
 #include "x11/gdkx.h"          /* For gdk_window_lookup() */
 #elif defined (GDK_WINDOWING_WIN32)
 #include "win32/gdkwin32.h"    /* For gdk_window_lookup() */
+#elif defined (GDK_WINDOWING_NANOX)
+#include "nanox/gdkprivate-nanox.h"    /* For gdk_window_lookup() */
 #endif
 
 #include "gtkmain.h"
index 3c649d08e659b1f5baaa5202c4b9e94fb0710e35..b73814229664f86fa87805fe6837bb4be4024178 100644 (file)
@@ -33,6 +33,8 @@
 #include "x11/gdkx.h"
 #elif defined (GDK_WINDOWING_WIN32)
 #include "win32/gdkwin32.h"
+#elif defined (GDK_WINDOWING_NANOX)
+#include "nanox/gdkprivate-nanox.h"
 #endif
 
 #include "gtkprivate.h"